From 21784920decc00fd35a51c49aaec233b7054155b Mon Sep 17 00:00:00 2001 From: Philoul Date: Sun, 28 Feb 2021 23:20:37 +0100 Subject: [PATCH 01/16] Fix witdth of Carbs Layout --- app/src/main/res/layout/dialog_carbs.xml | 89 +++++++++--------------- 1 file changed, 32 insertions(+), 57 deletions(-) diff --git a/app/src/main/res/layout/dialog_carbs.xml b/app/src/main/res/layout/dialog_carbs.xml index f0f306c6ff..6e485a0edb 100644 --- a/app/src/main/res/layout/dialog_carbs.xml +++ b/app/src/main/res/layout/dialog_carbs.xml @@ -77,16 +77,19 @@ + android:layout_height="match_parent" + android:layout_gravity="center_vertical"> @@ -115,11 +120,6 @@ android:padding="2dp" /> - - - + android:layout_height="match_parent" + android:layout_gravity="center_vertical"> - + android:layout_weight="1" + android:padding="10dp" + android:width="120dp" + android:text="@string/careportal_newnstreatment_duration_label" + android:textAppearance="@style/TextAppearance.AppCompat.Small" + android:textStyle="bold" /> - + - - - + android:layout_gravity="center_vertical" + android:gravity="start" + android:paddingStart="5dp" + android:paddingEnd="5dp" + android:text="@string/shorthour" + android:textAppearance="?android:attr/textAppearanceSmall" /> - - - - - - - + android:layout_height="match_parent" + android:layout_gravity="center_vertical"> - - - - From 65770ecbf67c1d8c2e18a212126dacaa379d9ee2 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 5 Mar 2021 21:19:53 +0100 Subject: [PATCH 02/16] RS pairing improvement --- core/src/main/res/values/strings.xml | 1 + .../nightscout/androidaps/danars/DanaRSPlugin.kt | 2 +- .../androidaps/danars/services/BLEComm.kt | 15 ++++++++++----- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/core/src/main/res/values/strings.xml b/core/src/main/res/values/strings.xml index fbeed450e7..9c6fe653ff 100644 --- a/core/src/main/res/values/strings.xml +++ b/core/src/main/res/values/strings.xml @@ -177,6 +177,7 @@ Bluetooth Low Energy not supported. + Bluetooth Low Energy not supported or device not paired. Bluetooth not enabled. Location Is Not Enabled For Bluetooth discovery to work on newer devices, location must be enabled. AAPS does not track your location and it can be disabled after pairing is successful. diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt b/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt index 07ce024d0c..799ef3af25 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/DanaRSPlugin.kt @@ -137,7 +137,7 @@ class DanaRSPlugin @Inject constructor( aapsLogger.debug(LTag.PUMP, "RS connect from: $reason") if (danaRSService != null && mDeviceAddress != "" && mDeviceName != "") { val success = danaRSService?.connect(reason, mDeviceAddress) ?: false - if (!success) ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.ble_not_supported)) + if (!success) ToastUtils.showToastInUiThread(context, resourceHelper.gs(R.string.ble_not_supported_or_not_paired)) } } diff --git a/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt b/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt index 1c0c3ab544..2b6eb98495 100644 --- a/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt +++ b/danars/src/main/java/info/nightscout/androidaps/danars/services/BLEComm.kt @@ -105,16 +105,21 @@ class BLEComm @Inject internal constructor( return false } - isConnected = false - v3Encryption = false - encryptedDataRead = false - encryptedCommandSent = false - isConnecting = true val device = bluetoothAdapter?.getRemoteDevice(address) if (device == null) { aapsLogger.error("Device not found. Unable to connect from: $from") return false } + if (device.bondState == BluetoothDevice.BOND_NONE) { + device.createBond() + SystemClock.sleep(10000) + return false + } + isConnected = false + v3Encryption = false + encryptedDataRead = false + encryptedCommandSent = false + isConnecting = true aapsLogger.debug(LTag.PUMPBTCOMM, "Trying to create a new connection from: $from") connectDeviceName = device.name bluetoothGatt = device.connectGatt(context, false, mGattCallback) From 23c23ea0b81583a07559e0261d3198474b8f3908 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 5 Mar 2021 23:08:43 +0100 Subject: [PATCH 03/16] TrendArrow calculation --- .../general/overview/OverviewFragment.kt | 3 +- .../androidaps/utils/TrendCalculator.kt | 45 +++++++++++++++++++ .../{ => extensions}/GlucoseValueUtils.kt | 0 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt rename app/src/main/java/info/nightscout/androidaps/utils/{ => extensions}/GlucoseValueUtils.kt (100%) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt index 3956e67fb6..86259bd729 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.kt @@ -109,6 +109,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList @Inject lateinit var fabricPrivacy: FabricPrivacy @Inject lateinit var overviewMenus: OverviewMenus @Inject lateinit var skinProvider: SkinProvider + @Inject lateinit var trendCalculator: TrendCalculator @Inject lateinit var config: Config @Inject lateinit var dateUtil: DateUtil @Inject lateinit var databaseHelper: DatabaseHelperInterface @@ -584,7 +585,7 @@ class OverviewFragment : DaggerFragment(), View.OnClickListener, OnLongClickList binding.infoLayout.bg.text = lastBG.valueToUnitsString(units) binding.infoLayout.bg.setTextColor(color) - binding.infoLayout.arrow.setImageResource(lastBG.trendArrow.directionToIcon()) + binding.infoLayout.arrow.setImageResource(trendCalculator.getTrendArrow(lastBG).directionToIcon()) binding.infoLayout.arrow.setColorFilter(color) val glucoseStatus = GlucoseStatus(injector).glucoseStatusData diff --git a/app/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt b/app/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt new file mode 100644 index 0000000000..ac7738043d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/utils/TrendCalculator.kt @@ -0,0 +1,45 @@ +package info.nightscout.androidaps.utils + +import info.nightscout.androidaps.database.AppRepository +import info.nightscout.androidaps.database.entities.GlucoseValue +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TrendCalculator @Inject constructor( + private val repository: AppRepository +) { + + fun getTrendArrow(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow = + if (glucoseValue.trendArrow != GlucoseValue.TrendArrow.NONE) glucoseValue.trendArrow + else calculateDirection(glucoseValue) + + private fun calculateDirection(glucoseValue: GlucoseValue): GlucoseValue.TrendArrow { + + val toTime = glucoseValue.timestamp + val readings = repository.compatGetBgReadingsDataFromTime(toTime - T.mins(10).msecs(), toTime, false).blockingGet() + + if (readings.size < 2) + return GlucoseValue.TrendArrow.NONE + val current = readings[0] + val previous = readings[1] + + // Avoid division by 0 + val slope = + if (current.timestamp == previous.timestamp) 0.0 + else (previous.value - current.value) / (previous.timestamp - current.timestamp) + + val slopeByMinute = slope * 60000 + + return when { + slopeByMinute <= -3.5 -> GlucoseValue.TrendArrow.DOUBLE_DOWN + slopeByMinute <= -2 -> GlucoseValue.TrendArrow.SINGLE_DOWN + slopeByMinute <= -1 -> GlucoseValue.TrendArrow.FORTY_FIVE_DOWN + slopeByMinute <= 1 -> GlucoseValue.TrendArrow.FLAT + slopeByMinute <= 2 -> GlucoseValue.TrendArrow.FORTY_FIVE_UP + slopeByMinute <= 3.5 -> GlucoseValue.TrendArrow.SINGLE_UP + slopeByMinute <= 40 -> GlucoseValue.TrendArrow.DOUBLE_UP + else -> GlucoseValue.TrendArrow.NONE + } + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/GlucoseValueUtils.kt b/app/src/main/java/info/nightscout/androidaps/utils/extensions/GlucoseValueUtils.kt similarity index 100% rename from app/src/main/java/info/nightscout/androidaps/utils/GlucoseValueUtils.kt rename to app/src/main/java/info/nightscout/androidaps/utils/extensions/GlucoseValueUtils.kt From 6ecdd4d7fc21ad9e4016f8c3fa7a58a491a1d5df Mon Sep 17 00:00:00 2001 From: Tim Gunn <2896311+Tornado-Tim@users.noreply.github.com> Date: Sun, 7 Mar 2021 02:53:01 +1300 Subject: [PATCH 04/16] Add appropriate constraint so isLgsAllowed Constraint can be properly checked --- .../plugins/configBuilder/ConstraintChecker.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt b/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt index 111dcd5b79..07b4f8f66b 100644 --- a/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt +++ b/core/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConstraintChecker.kt @@ -18,6 +18,9 @@ class ConstraintChecker @Inject constructor(private val activePlugin: ActivePlug fun isClosedLoopAllowed(): Constraint = isClosedLoopAllowed(Constraint(true)) + fun isLgsAllowed(): Constraint = + isLgsAllowed(Constraint(true)) + fun isAutosensModeEnabled(): Constraint = isAutosensModeEnabled(Constraint(true)) @@ -77,6 +80,16 @@ class ConstraintChecker @Inject constructor(private val activePlugin: ActivePlug return value } + override fun isLgsAllowed(value: Constraint): Constraint { + val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(ConstraintsInterface::class.java) + for (p in constraintsPlugins) { + val constraint = p as ConstraintsInterface + if (!p.isEnabled(PluginType.CONSTRAINTS)) continue + constraint.isLgsAllowed(value) + } + return value + } + override fun isAutosensModeEnabled(value: Constraint): Constraint { val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(ConstraintsInterface::class.java) for (p in constraintsPlugins) { From 9b78839f5d43ad312529199ced0a72dcc160b4f4 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sat, 6 Mar 2021 23:18:57 +0100 Subject: [PATCH 05/16] typo --- .../info/nightscout/androidaps/utils/ui/NumberPicker.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java b/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java index b90b25a81c..ad8ed67049 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java +++ b/core/src/main/java/info/nightscout/androidaps/utils/ui/NumberPicker.java @@ -188,11 +188,11 @@ public class NumberPicker extends LinearLayout implements View.OnKeyListener, }); } - public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formater, boolean allowZero, Button okButton, TextWatcher textWatcher) { + public void setParams(Double initValue, Double minValue, Double maxValue, Double step, NumberFormat formatter, boolean allowZero, Button okButton, TextWatcher textWatcher) { if (this.textWatcher != null) { editText.removeTextChangedListener(this.textWatcher); } - setParams(initValue, minValue, maxValue, step, formater, allowZero, okButton); + setParams(initValue, minValue, maxValue, step, formatter, allowZero, okButton); this.textWatcher = textWatcher; if (textWatcher != null) editText.addTextChangedListener(textWatcher); From 72176edfb9d82510117354ccacf177da59662f75 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 7 Mar 2021 00:49:18 +0100 Subject: [PATCH 06/16] core -> kt, move tests to core --- .../plugins/treatments/TreatmentsPlugin.java | 10 +- .../info/nightscout/androidaps/data/Iob.java | 47 ----- .../info/nightscout/androidaps/data/Iob.kt | 40 ++++ .../nightscout/androidaps/data/IobTotal.java | 190 ------------------ .../nightscout/androidaps/data/IobTotal.kt | 163 +++++++++++++++ .../nightscout/androidaps/data/MealData.java | 15 -- .../nightscout/androidaps/data/MealData.kt | 13 ++ .../data/NonOverlappingIntervals.java | 39 ---- .../data/NonOverlappingIntervals.kt | 26 +++ .../androidaps/data/OverlappingIntervals.java | 51 ----- .../androidaps/data/OverlappingIntervals.kt | 38 ++++ .../androidaps/data/ProfileIntervals.java | 132 ------------ .../androidaps/data/ProfileIntervals.kt | 115 +++++++++++ .../androidaps/db/ExtendedBolus.java | 8 +- .../androidaps/db/TemporaryBasal.java | 8 +- .../androidaps/TestBaseWithProfile.kt | 82 ++++++++ .../nightscout/androidaps/TestPumpPlugin.kt | 67 ++++++ .../androidaps/data}/ConstraintTest.kt | 8 +- .../androidaps/data/DetailedBolusInfoTest.kt | 0 .../nightscout/androidaps/data/IobTest.kt | 1 + .../androidaps/data/IobTotalTest.kt | 3 +- .../androidaps/data/MealDataTest.kt | 0 .../data/NonOverlappingIntervalsTest.kt | 0 .../data/OverlappingIntervalsTest.kt | 0 .../androidaps/data/ProfileIntervalsTest.kt | 22 +- .../nightscout/androidaps/data/ProfileTest.kt | 34 ++-- .../androidaps/data/PumpEnactResultTest.kt | 5 +- .../androidaps/data/TempTargetTest.kt | 0 .../data/defaultProfile/DefaultProfileTest.kt | 0 .../interfaces/PluginDescriptionTest.kt | 8 +- .../interfaces/PumpDescriptionTest.kt | 2 +- .../plugins/aps/loop/APSResultTest.kt | 22 +- .../formats}/ClassicPrefsFormatTest.kt | 5 +- .../formats}/EncryptedPrefsFormatTest.kt | 4 +- .../formats}/SingleStringStorage.kt | 38 ++-- .../iob/iobCalculator}/GlucoseStatusTest.kt | 11 +- .../bolusInfo/DetailedBolusInfoStorageTest.kt | 5 +- .../pump/common/utils/DateTimeUtilUTest.java | 4 +- .../androidaps/utils/MidnightTimeTest.java | 0 39 files changed, 636 insertions(+), 580 deletions(-) delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/Iob.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/Iob.kt delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/IobTotal.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/MealData.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/MealData.kt delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.kt delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.kt delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.kt create mode 100644 core/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt create mode 100644 core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt rename {app/src/test/java/info/nightscout/androidaps/interfaces => core/src/test/java/info/nightscout/androidaps/data}/ConstraintTest.kt (93%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt (100%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/IobTest.kt (96%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/IobTotalTest.kt (98%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/MealDataTest.kt (100%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/NonOverlappingIntervalsTest.kt (100%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt (100%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/ProfileIntervalsTest.kt (82%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt (66%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/PumpEnactResultTest.kt (98%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/TempTargetTest.kt (100%) rename {app => core}/src/test/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfileTest.kt (100%) rename {app => core}/src/test/java/info/nightscout/androidaps/interfaces/PluginDescriptionTest.kt (90%) rename app/src/test/java/info/nightscout/androidaps/interfaces/PumpDescritpionTest.kt => core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt (99%) rename {app => core}/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt (91%) rename {app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance => core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats}/ClassicPrefsFormatTest.kt (85%) rename {app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance => core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats}/EncryptedPrefsFormatTest.kt (98%) rename {app/src/test/java/info/nightscout/androidaps/testing/utils => core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats}/SingleStringStorage.kt (84%) rename {app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator => core/src/test/java/info/nightscout/androidaps/plugins/iob/iobCalculator}/GlucoseStatusTest.kt (96%) rename {app/src/test/java/info/nightscout/androidaps/plugins/pump/common => core/src/test/java/info/nightscout/androidaps/pump}/bolusInfo/DetailedBolusInfoStorageTest.kt (93%) rename {app/src/test/java/info/nightscout/androidaps/plugins => core/src/test/java/info/nightscout/androidaps}/pump/common/utils/DateTimeUtilUTest.java (79%) rename {app => core}/src/test/java/info/nightscout/androidaps/utils/MidnightTimeTest.java (100%) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java index a30f7efc51..f3e1d6c34e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java @@ -250,8 +250,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface if (!t.isValid) continue; if (t.date > time) continue; Iob tIOB = t.iobCalc(time, dia); - total.iob += tIOB.iobContrib; - total.activity += tIOB.activityContrib; + total.iob += tIOB.getIobContrib(); + total.activity += tIOB.getActivityContrib(); if (t.insulin > 0 && t.date > total.lastBolusTime) total.lastBolusTime = t.date; if (!t.isSMB) { @@ -260,7 +260,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface long timeSinceTreatment = time - t.date; long snoozeTime = t.date + (long) (timeSinceTreatment * sp.getDouble(R.string.key_openapsama_bolussnooze_dia_divisor, 2.0)); Iob bIOB = t.iobCalc(snoozeTime, dia); - total.bolussnooze += bIOB.iobContrib; + total.bolussnooze += bIOB.getIobContrib(); } } } @@ -476,8 +476,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface treatment.date = i; treatment.insulin = running * 5.0 / 60.0; // 5 min chunk Iob iob = treatment.iobCalc(time, profile.getDia()); - total.basaliob += iob.iobContrib; - total.activity += iob.activityContrib; + total.basaliob += iob.getIobContrib(); + total.activity += iob.getActivityContrib(); } return total; } diff --git a/core/src/main/java/info/nightscout/androidaps/data/Iob.java b/core/src/main/java/info/nightscout/androidaps/data/Iob.java deleted file mode 100644 index d48cdf627c..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/data/Iob.java +++ /dev/null @@ -1,47 +0,0 @@ -package info.nightscout.androidaps.data; - -/** - * Created by mike on 05.06.2016. - */ -public class Iob { - public double iobContrib = 0d; - public double activityContrib = 0d; - - public Iob iobContrib(double iobContrib) { - this.iobContrib = iobContrib; - return this; - } - - public Iob activityContrib(double activityContrib) { - this.activityContrib = activityContrib; - return this; - } - - public Iob plus(Iob iob) { - iobContrib += iob.iobContrib; - activityContrib += iob.activityContrib; - return this; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - - Iob iob = (Iob) o; - - if (Double.compare(iob.iobContrib, iobContrib) != 0) return false; - return Double.compare(iob.activityContrib, activityContrib) == 0; - } - - @Override - public int hashCode() { - int result; - long temp; - temp = Double.doubleToLongBits(iobContrib); - result = (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(activityContrib); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - return result; - } -} diff --git a/core/src/main/java/info/nightscout/androidaps/data/Iob.kt b/core/src/main/java/info/nightscout/androidaps/data/Iob.kt new file mode 100644 index 0000000000..8cf734a625 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/data/Iob.kt @@ -0,0 +1,40 @@ +package info.nightscout.androidaps.data + +class Iob { + + var iobContrib = 0.0 + var activityContrib = 0.0 + + fun iobContrib(iobContrib: Double): Iob { + this.iobContrib = iobContrib + return this + } + + fun activityContrib(activityContrib: Double): Iob { + this.activityContrib = activityContrib + return this + } + + operator fun plus(iob: Iob): Iob { + iobContrib += iob.iobContrib + activityContrib += iob.activityContrib + return this + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other == null || javaClass != other.javaClass) return false + val iob = other as Iob + return if (iob.iobContrib.compareTo(iobContrib) != 0) false + else iob.activityContrib.compareTo(activityContrib) == 0 + } + + override fun hashCode(): Int { + var result: Int + var temp: Long = java.lang.Double.doubleToLongBits(iobContrib) + result = (temp xor (temp ushr 32)).toInt() + temp = java.lang.Double.doubleToLongBits(activityContrib) + result = 31 * result + (temp xor (temp ushr 32)).toInt() + return result + } +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/IobTotal.java b/core/src/main/java/info/nightscout/androidaps/data/IobTotal.java deleted file mode 100644 index adefc76767..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/data/IobTotal.java +++ /dev/null @@ -1,190 +0,0 @@ -package info.nightscout.androidaps.data; - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Date; - -import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface; -import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries; -import info.nightscout.androidaps.utils.DateUtil; -import info.nightscout.androidaps.utils.Round; - -public class IobTotal implements DataPointWithLabelInterface { - - public double iob; - public double activity; - public double bolussnooze; - public double basaliob; - public double netbasalinsulin; - public double hightempinsulin; - - // oref1 - public long lastBolusTime; - public IobTotal iobWithZeroTemp; - - public double netInsulin = 0d; // for calculations from temp basals only - public double netRatio = 0d; // net ratio at start of temp basal - - public double extendedBolusInsulin = 0d; // total insulin for extended bolus - - long time; - - - public IobTotal copy() { - IobTotal i = new IobTotal(time); - i.iob = iob; - i.activity = activity; - i.bolussnooze = bolussnooze; - i.basaliob = basaliob; - i.netbasalinsulin = netbasalinsulin; - i.hightempinsulin = hightempinsulin; - i.lastBolusTime = lastBolusTime; - if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp.copy(); - i.netInsulin = netInsulin; - i.netRatio = netRatio; - i.extendedBolusInsulin = extendedBolusInsulin; - return i; - } - - public IobTotal(long time) { - this.iob = 0d; - this.activity = 0d; - this.bolussnooze = 0d; - this.basaliob = 0d; - this.netbasalinsulin = 0d; - this.hightempinsulin = 0d; - this.lastBolusTime = 0; - this.time = time; - } - - public IobTotal plus(IobTotal other) { - iob += other.iob; - activity += other.activity; - bolussnooze += other.bolussnooze; - basaliob += other.basaliob; - netbasalinsulin += other.netbasalinsulin; - hightempinsulin += other.hightempinsulin; - netInsulin += other.netInsulin; - extendedBolusInsulin += other.extendedBolusInsulin; - return this; - } - - public static IobTotal combine(IobTotal bolusIOB, IobTotal basalIob) { - IobTotal result = new IobTotal(bolusIOB.time); - result.iob = bolusIOB.iob + basalIob.basaliob; - result.activity = bolusIOB.activity + basalIob.activity; - result.bolussnooze = bolusIOB.bolussnooze; - result.basaliob = bolusIOB.basaliob + basalIob.basaliob; - result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin; - result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin; - result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin; - result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin; - result.lastBolusTime = bolusIOB.lastBolusTime; - result.iobWithZeroTemp = basalIob.iobWithZeroTemp; - return result; - } - - public IobTotal round() { - this.iob = Round.roundTo(this.iob, 0.001); - this.activity = Round.roundTo(this.activity, 0.0001); - this.bolussnooze = Round.roundTo(this.bolussnooze, 0.0001); - this.basaliob = Round.roundTo(this.basaliob, 0.001); - this.netbasalinsulin = Round.roundTo(this.netbasalinsulin, 0.001); - this.hightempinsulin = Round.roundTo(this.hightempinsulin, 0.001); - this.netInsulin = Round.roundTo(this.netInsulin, 0.001); - this.extendedBolusInsulin = Round.roundTo(this.extendedBolusInsulin, 0.001); - return this; - } - - public JSONObject json() { - JSONObject json = new JSONObject(); - try { - json.put("iob", iob); - json.put("basaliob", basaliob); - json.put("activity", activity); - json.put("time", DateUtil.toISOString(new Date())); - } catch (JSONException ignored) { - } - return json; - } - - public JSONObject determineBasalJson() { - JSONObject json = new JSONObject(); - try { - json.put("iob", iob); - json.put("basaliob", basaliob); - json.put("bolussnooze", bolussnooze); - json.put("activity", activity); - json.put("lastBolusTime", lastBolusTime); - json.put("time", DateUtil.toISOString(new Date(time))); - /* - - This is requested by SMB determine_basal but by based on Scott's info - it's MDT specific safety check only - It's causing rounding issues in determine_basal - - JSONObject lastTemp = new JSONObject(); - lastTemp.put("date", lastTempDate); - lastTemp.put("rate", lastTempRate); - lastTemp.put("duration", lastTempDuration); - json.put("lastTemp", lastTemp); - */ - if (iobWithZeroTemp != null) { - JSONObject iwzt = iobWithZeroTemp.determineBasalJson(); - json.put("iobWithZeroTemp", iwzt); - } - } catch (JSONException ignored) { - } - return json; - } - - // DataPoint interface - - private int color; - - @Override - public double getX() { - return time; - } - - @Override - public double getY() { - return iob; - } - - @Override - public void setY(double y) { - - } - - @Override - public String getLabel() { - return null; - } - - @Override - public long getDuration() { - return 0; - } - - @Override - public PointsWithLabelGraphSeries.Shape getShape() { - return PointsWithLabelGraphSeries.Shape.IOBPREDICTION; - } - - @Override - public float getSize() { - return 0.5f; - } - - @Override - public int getColor() { - return color; - } - - public IobTotal setColor(int color) { - this.color = color; - return this; - } -} diff --git a/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt b/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt new file mode 100644 index 0000000000..b295f66416 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/data/IobTotal.kt @@ -0,0 +1,163 @@ +package info.nightscout.androidaps.data + +import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface +import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.Round +import org.json.JSONException +import org.json.JSONObject +import java.util.* + +@Suppress("SpellCheckingInspection") +class IobTotal(var time: Long) : DataPointWithLabelInterface { + + @JvmField var iob = 0.0 + @JvmField var activity = 0.0 + @JvmField var bolussnooze = 0.0 + @JvmField var basaliob = 0.0 + @JvmField var netbasalinsulin = 0.0 + @JvmField var hightempinsulin = 0.0 + + // oref1 + @JvmField var lastBolusTime: Long = 0 + var iobWithZeroTemp: IobTotal? = null + @JvmField var netInsulin = 0.0 // for calculations from temp basals only + @JvmField var netRatio = 0.0 // net ratio at start of temp basal + @JvmField var extendedBolusInsulin = 0.0 // total insulin for extended bolus + fun copy(): IobTotal { + val i = IobTotal(time) + i.iob = iob + i.activity = activity + i.bolussnooze = bolussnooze + i.basaliob = basaliob + i.netbasalinsulin = netbasalinsulin + i.hightempinsulin = hightempinsulin + i.lastBolusTime = lastBolusTime + if (iobWithZeroTemp != null) i.iobWithZeroTemp = iobWithZeroTemp!!.copy() + i.netInsulin = netInsulin + i.netRatio = netRatio + i.extendedBolusInsulin = extendedBolusInsulin + return i + } + + operator fun plus(other: IobTotal): IobTotal { + iob += other.iob + activity += other.activity + bolussnooze += other.bolussnooze + basaliob += other.basaliob + netbasalinsulin += other.netbasalinsulin + hightempinsulin += other.hightempinsulin + netInsulin += other.netInsulin + extendedBolusInsulin += other.extendedBolusInsulin + return this + } + + fun round(): IobTotal { + iob = Round.roundTo(iob, 0.001) + activity = Round.roundTo(activity, 0.0001) + bolussnooze = Round.roundTo(bolussnooze, 0.0001) + basaliob = Round.roundTo(basaliob, 0.001) + netbasalinsulin = Round.roundTo(netbasalinsulin, 0.001) + hightempinsulin = Round.roundTo(hightempinsulin, 0.001) + netInsulin = Round.roundTo(netInsulin, 0.001) + extendedBolusInsulin = Round.roundTo(extendedBolusInsulin, 0.001) + return this + } + + fun json(): JSONObject { + val json = JSONObject() + try { + json.put("iob", iob) + json.put("basaliob", basaliob) + json.put("activity", activity) + json.put("time", DateUtil.toISOString(Date())) + } catch (ignored: JSONException) { + } + return json + } + + fun determineBasalJson(): JSONObject { + val json = JSONObject() + try { + json.put("iob", iob) + json.put("basaliob", basaliob) + json.put("bolussnooze", bolussnooze) + json.put("activity", activity) + json.put("lastBolusTime", lastBolusTime) + json.put("time", DateUtil.toISOString(Date(time))) + /* + + This is requested by SMB determine_basal but by based on Scott's info + it's MDT specific safety check only + It's causing rounding issues in determine_basal + + JSONObject lastTemp = new JSONObject(); + lastTemp.put("date", lastTempDate); + lastTemp.put("rate", lastTempRate); + lastTemp.put("duration", lastTempDuration); + json.put("lastTemp", lastTemp); + */ + if (iobWithZeroTemp != null) { + val iwzt = iobWithZeroTemp!!.determineBasalJson() + json.put("iobWithZeroTemp", iwzt) + } + } catch (ignored: JSONException) { + } + return json + } + + // DataPoint interface + private var color = 0 + override fun getX(): Double { + return time.toDouble() + } + + override fun getY(): Double { + return iob + } + + override fun setY(y: Double) {} + + override fun getLabel(): String { + return "" + } + + override fun getDuration(): Long { + return 0 + } + + override fun getShape(): PointsWithLabelGraphSeries.Shape { + return PointsWithLabelGraphSeries.Shape.IOBPREDICTION + } + + override fun getSize(): Float { + return 0.5f + } + + override fun getColor(): Int { + return color + } + + fun setColor(color: Int): IobTotal { + this.color = color + return this + } + + companion object { + + fun combine(bolusIOB: IobTotal, basalIob: IobTotal): IobTotal { + val result = IobTotal(bolusIOB.time) + result.iob = bolusIOB.iob + basalIob.basaliob + result.activity = bolusIOB.activity + basalIob.activity + result.bolussnooze = bolusIOB.bolussnooze + result.basaliob = bolusIOB.basaliob + basalIob.basaliob + result.netbasalinsulin = bolusIOB.netbasalinsulin + basalIob.netbasalinsulin + result.hightempinsulin = basalIob.hightempinsulin + bolusIOB.hightempinsulin + result.netInsulin = basalIob.netInsulin + bolusIOB.netInsulin + result.extendedBolusInsulin = basalIob.extendedBolusInsulin + bolusIOB.extendedBolusInsulin + result.lastBolusTime = bolusIOB.lastBolusTime + result.iobWithZeroTemp = basalIob.iobWithZeroTemp + return result + } + } +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/MealData.java b/core/src/main/java/info/nightscout/androidaps/data/MealData.java deleted file mode 100644 index 8acf4285bf..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/data/MealData.java +++ /dev/null @@ -1,15 +0,0 @@ -package info.nightscout.androidaps.data; - -/** - * Created by mike on 04.01.2017. - */ -public class MealData { - public double boluses = 0d; - public double carbs = 0d; - public double mealCOB = 0.0d; - public double slopeFromMaxDeviation = 0; - public double slopeFromMinDeviation = 999; - public long lastBolusTime; - public long lastCarbTime = 0L; - public double usedMinCarbsImpact = 0d; -} diff --git a/core/src/main/java/info/nightscout/androidaps/data/MealData.kt b/core/src/main/java/info/nightscout/androidaps/data/MealData.kt new file mode 100644 index 0000000000..3084c636c6 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/data/MealData.kt @@ -0,0 +1,13 @@ +package info.nightscout.androidaps.data + +class MealData { + + var boluses = 0.0 + var carbs = 0.0 + var mealCOB = 0.0 + var slopeFromMaxDeviation = 0.0 + var slopeFromMinDeviation = 999.0 + var lastBolusTime: Long = 0 + var lastCarbTime = 0L + var usedMinCarbsImpact = 0.0 +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java b/core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java deleted file mode 100644 index c426aede40..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.java +++ /dev/null @@ -1,39 +0,0 @@ -package info.nightscout.androidaps.data; - - -import androidx.annotation.Nullable; - -import info.nightscout.androidaps.interfaces.Interval; - -/** - * Created by adrian on 15/07/17. - */ - -public class NonOverlappingIntervals extends Intervals { - - public NonOverlappingIntervals() { - super(); - } - - public NonOverlappingIntervals (Intervals other) { - rawData = other.rawData.clone(); - } - - public synchronized void merge() { - for (int index = 0; index < rawData.size() - 1; index++) { - Interval i = rawData.valueAt(index); - long startOfNewer = rawData.valueAt(index + 1).start(); - if (i.originalEnd() > startOfNewer) { - i.cutEndTo(startOfNewer); - } - } - } - - @Nullable - public synchronized T getValueByInterval(long time) { - int index = binarySearch(time); - if (index >= 0) return rawData.valueAt(index); - return null; - } - -} diff --git a/core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.kt b/core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.kt new file mode 100644 index 0000000000..9c8b642baf --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/data/NonOverlappingIntervals.kt @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.data + +import info.nightscout.androidaps.interfaces.Interval + +class NonOverlappingIntervals : Intervals { + + constructor() : super() + constructor(other: Intervals) { + rawData = other.rawData.clone() + } + + @Synchronized public override fun merge() { + for (index in 0 until rawData.size() - 1) { + val i: T = rawData.valueAt(index) + val startOfNewer = rawData.valueAt(index + 1).start() + if (i.originalEnd() > startOfNewer) { + i.cutEndTo(startOfNewer) + } + } + } + + @Synchronized override fun getValueByInterval(time: Long): T? { + val index = binarySearch(time) + return if (index >= 0) rawData.valueAt(index) else null + } +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java b/core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java deleted file mode 100644 index 5515ea15e1..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.java +++ /dev/null @@ -1,51 +0,0 @@ -package info.nightscout.androidaps.data; - - -import androidx.annotation.Nullable; - -import info.nightscout.androidaps.interfaces.Interval; - -/** - * Created by adrian on 15/07/17. - */ - -public class OverlappingIntervals extends Intervals { - - public OverlappingIntervals() { - super(); - } - - public OverlappingIntervals(Intervals other) { - rawData = other.rawData.clone(); - } - - protected synchronized void merge() { - boolean needToCut = false; - long cutTime = 0; - - for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest - Interval cur = rawData.valueAt(index); - if (cur.isEndingEvent()) { - needToCut = true; - cutTime = cur.start(); - } else { - //event that is no EndingEvent might need to be stopped by an ending event - if (needToCut && cur.end() > cutTime) { - cur.cutEndTo(cutTime); - } - } - } - } - - @Nullable - public synchronized T getValueByInterval(long time) { - for (int index = rawData.size() - 1; index >= 0; index--) { //begin with newest - T cur = rawData.valueAt(index); - if (cur.match(time)) { - return cur; - } - } - return null; - } - -} diff --git a/core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.kt b/core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.kt new file mode 100644 index 0000000000..ad6d189b3b --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/data/OverlappingIntervals.kt @@ -0,0 +1,38 @@ +package info.nightscout.androidaps.data + +import info.nightscout.androidaps.interfaces.Interval + +class OverlappingIntervals : Intervals { + + constructor() : super() + constructor(other: Intervals) { + rawData = other.rawData.clone() + } + + @Synchronized override fun merge() { + var needToCut = false + var cutTime: Long = 0 + for (index in rawData.size() - 1 downTo 0) { //begin with newest + val cur: Interval = rawData.valueAt(index) + if (cur.isEndingEvent) { + needToCut = true + cutTime = cur.start() + } else { + //event that is no EndingEvent might need to be stopped by an ending event + if (needToCut && cur.end() > cutTime) { + cur.cutEndTo(cutTime) + } + } + } + } + + @Synchronized override fun getValueByInterval(time: Long): T? { + for (index in rawData.size() - 1 downTo 0) { //begin with newest + val cur = rawData.valueAt(index) + if (cur!!.match(time)) { + return cur + } + } + return null + } +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java b/core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java deleted file mode 100644 index 6e68c3996a..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.java +++ /dev/null @@ -1,132 +0,0 @@ -package info.nightscout.androidaps.data; - -import androidx.annotation.Nullable; -import androidx.collection.LongSparseArray; - -import java.util.ArrayList; -import java.util.List; - -import info.nightscout.androidaps.interfaces.Interval; - -/** - * Created by mike on 09.05.2017. - */ - -// Zero duration means profile is valid until is chaged -// When no interval match the lastest record without duration is used - -public class ProfileIntervals { - - private LongSparseArray rawData; // oldest at index 0 - - public ProfileIntervals() { - rawData = new LongSparseArray<>(); - } - - public ProfileIntervals(ProfileIntervals other) { - rawData = other.rawData.clone(); - } - - public synchronized ProfileIntervals reset() { - rawData = new LongSparseArray<>(); - return this; - } - - public synchronized void add(T newInterval) { - if (newInterval.isValid()) { - rawData.put(newInterval.start(), newInterval); - merge(); - } - } - - public synchronized void add(List list) { - for (T interval : list) { - if (interval.isValid()) - rawData.put(interval.start(), interval); - } - merge(); - } - - private synchronized void merge() { - for (int index = 0; index < rawData.size() - 1; index++) { - Interval i = rawData.valueAt(index); - long startOfNewer = rawData.valueAt(index + 1).start(); - if (i.originalEnd() > startOfNewer) { - i.cutEndTo(startOfNewer); - } - } - } - - @Nullable - public synchronized Interval getValueToTime(long time) { - int index = binarySearch(time); - if (index >= 0) return rawData.valueAt(index); - // if we request data older than first record, use oldest with zero duration instead - for (index = 0; index < rawData.size(); index++) { - if (rawData.valueAt(index).durationInMsec() == 0) { - //log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); - return rawData.valueAt(index); - } - } - return null; - } - - public synchronized List getList() { - List list = new ArrayList<>(); - for (int i = 0; i < rawData.size(); i++) - list.add(rawData.valueAt(i)); - return list; - } - - public synchronized List getReversedList() { - List list = new ArrayList<>(); - for (int i = rawData.size() - 1; i >= 0; i--) - list.add(rawData.valueAt(i)); - return list; - } - - private synchronized int binarySearch(long value) { - if (rawData.size() == 0) - return -1; - int lo = 0; - int hi = rawData.size() - 1; - - while (lo <= hi) { - final int mid = (lo + hi) >>> 1; - final Interval midVal = rawData.valueAt(mid); - - if (midVal.match(value)) { - return mid; // value found - } else if (midVal.before(value)) { - lo = mid + 1; - } else if (midVal.after(value)) { - hi = mid - 1; - } - } - // not found, try nearest older with duration 0 - lo = lo - 1; - while (lo >= 0 && lo < rawData.size()) { - if (rawData.valueAt(lo).isEndingEvent()) - return lo; - lo--; - } - return -1; // value not present - } - - public synchronized int size() { - return rawData.size(); - } - - public synchronized T get(int index) { - return rawData.valueAt(index); - } - - public synchronized T getReversed(int index) { - return rawData.valueAt(size() - 1 - index); - } - - @Override - public String toString() { - return rawData.toString(); - } -} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.kt b/core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.kt new file mode 100644 index 0000000000..1f7097b59b --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/data/ProfileIntervals.kt @@ -0,0 +1,115 @@ +package info.nightscout.androidaps.data + +import androidx.collection.LongSparseArray +import info.nightscout.androidaps.interfaces.Interval +import java.util.* + +// Zero duration means profile is valid until is changed +// When no interval match the latest record without duration is used +class ProfileIntervals { + + private var rawData: LongSparseArray // oldest at index 0 + + constructor() { + rawData = LongSparseArray() + } + + constructor(other: ProfileIntervals) { + rawData = other.rawData.clone() + } + + @Synchronized fun reset(): ProfileIntervals { + rawData = LongSparseArray() + return this + } + + @Synchronized fun add(newInterval: T) { + if (newInterval.isValid) { + rawData.put(newInterval.start(), newInterval) + merge() + } + } + + @Synchronized fun add(list: List) { + for (interval in list) { + if (interval.isValid) rawData.put(interval.start(), interval) + } + merge() + } + + @Synchronized private fun merge() { + for (index in 0 until rawData.size() - 1) { + val i: T = rawData.valueAt(index) + val startOfNewer = rawData.valueAt(index + 1)!!.start() + if (i.originalEnd() > startOfNewer) { + i.cutEndTo(startOfNewer) + } + } + } + + @Synchronized fun getValueToTime(time: Long): Interval? { + var index = binarySearch(time) + if (index >= 0) return rawData.valueAt(index) + // if we request data older than first record, use oldest with zero duration instead + index = 0 + while (index < rawData.size()) { + if (rawData.valueAt(index)!!.durationInMsec() == 0L) { + //log.debug("Requested profile for time: " + DateUtil.dateAndTimeString(time) + ". Providing oldest record: " + rawData.valueAt(0).toString()); + return rawData.valueAt(index) + } + index++ + } + return null + } + + @get:Synchronized val list: List + get() { + val list: MutableList = ArrayList() + for (i in 0 until rawData.size()) list.add(rawData.valueAt(i)) + return list + } + @get:Synchronized val reversedList: List + get() { + val list: MutableList = ArrayList() + for (i in rawData.size() - 1 downTo 0) list.add(rawData.valueAt(i)) + return list + } + + @Synchronized private fun binarySearch(value: Long): Int { + if (rawData.size() == 0) return -1 + var lo = 0 + var hi = rawData.size() - 1 + while (lo <= hi) { + val mid = lo + hi ushr 1 + val midVal: Interval = rawData.valueAt(mid) + when { + midVal.match(value) -> return mid // value found + midVal.before(value) -> lo = mid + 1 + midVal.after(value) -> hi = mid - 1 + } + } + // not found, try nearest older with duration 0 + lo -= 1 + while (lo >= 0 && lo < rawData.size()) { + if (rawData.valueAt(lo)!!.isEndingEvent) return lo + lo-- + } + return -1 // value not present + } + + @Synchronized fun size(): Int { + return rawData.size() + } + + @Synchronized operator fun get(index: Int): T? { + return rawData.valueAt(index) + } + + @Synchronized fun getReversed(index: Int): T { + return rawData.valueAt(size() - 1 - index) + } + + override fun toString(): String { + return rawData.toString() + } +} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java b/core/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java index ccb83b9781..a3ce5d9fd1 100644 --- a/core/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java +++ b/core/src/main/java/info/nightscout/androidaps/db/ExtendedBolus.java @@ -254,8 +254,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { tempBolusPart.date = calcdate; Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); - result.iob += aIOB.iobContrib; - result.activity += aIOB.activityContrib; + result.iob += aIOB.getIobContrib(); + result.activity += aIOB.getActivityContrib(); result.extendedBolusInsulin += tempBolusPart.insulin; } } @@ -305,8 +305,8 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface { tempBolusPart.date = calcdate; Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); - result.iob += aIOB.iobContrib; - result.activity += aIOB.activityContrib; + result.iob += aIOB.getIobContrib(); + result.activity += aIOB.getActivityContrib(); result.extendedBolusInsulin += tempBolusPart.insulin; } } diff --git a/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java b/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java index 6623e54624..7c591e0602 100644 --- a/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java +++ b/core/src/main/java/info/nightscout/androidaps/db/TemporaryBasal.java @@ -285,8 +285,8 @@ public class TemporaryBasal implements Interval, DbObjectBase { tempBolusPart.date = calcdate; Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); - result.basaliob += aIOB.iobContrib; - result.activity += aIOB.activityContrib; + result.basaliob += aIOB.getIobContrib(); + result.activity += aIOB.getActivityContrib(); result.netbasalinsulin += tempBolusPart.insulin; if (tempBolusPart.insulin > 0) { result.hightempinsulin += tempBolusPart.insulin; @@ -352,8 +352,8 @@ public class TemporaryBasal implements Interval, DbObjectBase { tempBolusPart.date = calcdate; Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia); - result.basaliob += aIOB.iobContrib; - result.activity += aIOB.activityContrib; + result.basaliob += aIOB.getIobContrib(); + result.activity += aIOB.getActivityContrib(); result.netbasalinsulin += tempBolusPart.insulin; if (tempBolusPart.insulin > 0) { result.hightempinsulin += tempBolusPart.insulin; diff --git a/core/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt b/core/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt new file mode 100644 index 0000000000..e3e5c7391b --- /dev/null +++ b/core/src/test/java/info/nightscout/androidaps/TestBaseWithProfile.kt @@ -0,0 +1,82 @@ +package info.nightscout.androidaps + +import dagger.android.AndroidInjector +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.db.ProfileSwitch +import info.nightscout.androidaps.db.Treatment +import info.nightscout.androidaps.interfaces.ActivePluginProvider +import info.nightscout.androidaps.interfaces.ConfigInterface +import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.interfaces.ProfileStore +import info.nightscout.androidaps.interfaces.TreatmentsInterface +import info.nightscout.androidaps.plugins.bus.RxBusWrapper +import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.DefaultValueHelper +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.resources.ResourceHelper +import org.json.JSONObject +import org.junit.Before +import org.mockito.Mock +import org.powermock.core.classloader.annotations.PrepareForTest + +@Suppress("SpellCheckingInspection") +@PrepareForTest(FabricPrivacy::class) +open class TestBaseWithProfile : TestBase() { + + @Mock lateinit var activePluginProvider: ActivePluginProvider + @Mock lateinit var resourceHelper: ResourceHelper + @Mock lateinit var treatmentsInterface: TreatmentsInterface + @Mock lateinit var fabricPrivacy: FabricPrivacy + @Mock lateinit var profileFunction: ProfileFunction + @Mock lateinit var defaultValueHelper: DefaultValueHelper + @Mock lateinit var dateUtil: DateUtil + @Mock lateinit var configInterface: ConfigInterface + + val rxBus = RxBusWrapper(aapsSchedulers) + + val profileInjector = HasAndroidInjector { + AndroidInjector { + if (it is Profile) { + it.aapsLogger = aapsLogger + it.activePlugin = activePluginProvider + it.resourceHelper = resourceHelper + it.rxBus = rxBus + it.fabricPrivacy = fabricPrivacy + it.configInterface = configInterface + } + if (it is ProfileSwitch) { + it.treatmentsPlugin = treatmentsInterface + it.aapsLogger = aapsLogger + it.rxBus = rxBus + it.resourceHelper = resourceHelper + it.dateUtil = dateUtil + } + if (it is Treatment) { + it.activePlugin = activePluginProvider + it.profileFunction = profileFunction + it.defaultValueHelper = defaultValueHelper + it.resourceHelper = resourceHelper + } + } + } + + private lateinit var validProfileJSON: String + lateinit var validProfile: Profile + @Suppress("PropertyName") val TESTPROFILENAME = "someProfile" + + @Before + fun prepareMock() { + validProfileJSON = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + validProfile = Profile(profileInjector, JSONObject(validProfileJSON), Constants.MGDL) + } + + fun getValidProfileStore(): ProfileStore { + val json = JSONObject() + val store = JSONObject() + store.put(TESTPROFILENAME, JSONObject(validProfileJSON)) + json.put("defaultProfile", TESTPROFILENAME) + json.put("store", store) + return ProfileStore(profileInjector, json) + } +} \ No newline at end of file diff --git a/core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt b/core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt new file mode 100644 index 0000000000..97727ab5af --- /dev/null +++ b/core/src/test/java/info/nightscout/androidaps/TestPumpPlugin.kt @@ -0,0 +1,67 @@ +package info.nightscout.androidaps + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.data.DetailedBolusInfo +import info.nightscout.androidaps.data.Profile +import info.nightscout.androidaps.data.PumpEnactResult +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.interfaces.PumpInterface +import info.nightscout.androidaps.plugins.common.ManufacturerType +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType +import info.nightscout.androidaps.utils.TimeChangeType +import org.json.JSONObject + +@Suppress("MemberVisibilityCanBePrivate") +class TestPumpPlugin(val injector: HasAndroidInjector) : PumpInterface { + + var connected = false + var isProfileSet = true + + override fun isConnected() = connected + override fun isConnecting() = false + override fun isHandshakeInProgress() = false + val lastData = 0L + + val baseBasal = 0.0 + override val pumpDescription = PumpDescription() + + override fun isInitialized(): Boolean = true + override fun isSuspended(): Boolean = false + override fun isBusy(): Boolean = false + override fun connect(reason: String) { + connected = true + } + + override fun disconnect(reason: String) { + connected = false + } + + override fun stopConnecting() { + connected = false + } + + override fun waitForDisconnectionInSeconds(): Int = 0 + override fun getPumpStatus(reason: String) {} + override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector) + override fun isThisProfileSet(profile: Profile): Boolean = isProfileSet + override fun lastDataTime(): Long = lastData + override val baseBasalRate: Double = baseBasal + override val reservoirLevel: Double = 0.0 + override val batteryLevel: Int = 0 + override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun stopBolusDelivering() {} + override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject() + override fun manufacturer(): ManufacturerType = ManufacturerType.AndroidAPS + override fun model(): PumpType = PumpType.GenericAAPS + override fun serialNumber(): String = "1" + override fun shortStatus(veryShort: Boolean): String = "" + override val isFakingTempsByExtendedBoluses: Boolean = false + override fun loadTDDs(): PumpEnactResult = PumpEnactResult(injector).success(true) + override fun canHandleDST(): Boolean = true + override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {} +} \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.kt b/core/src/test/java/info/nightscout/androidaps/data/ConstraintTest.kt similarity index 93% rename from app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/ConstraintTest.kt index a41d7c1630..8259d37968 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/ConstraintTest.kt @@ -1,14 +1,12 @@ -package info.nightscout.androidaps.interfaces +package info.nightscout.androidaps.data import info.nightscout.androidaps.TestBase -import info.nightscout.androidaps.MainApp -import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.utils.sharedPreferences.SP import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner @@ -16,7 +14,7 @@ import org.powermock.modules.junit4.PowerMockRunner * Created by mike on 19.03.2018. */ @RunWith(PowerMockRunner::class) -@PrepareForTest(MainApp::class, SP::class) +@PrepareForTest(SP::class) class ConstraintTest : TestBase() { @Test fun doTests() { diff --git a/app/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt b/core/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt similarity index 100% rename from app/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/DetailedBolusInfoTest.kt diff --git a/app/src/test/java/info/nightscout/androidaps/data/IobTest.kt b/core/src/test/java/info/nightscout/androidaps/data/IobTest.kt similarity index 96% rename from app/src/test/java/info/nightscout/androidaps/data/IobTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/IobTest.kt index ed5837ea0a..7a550b03f6 100644 --- a/app/src/test/java/info/nightscout/androidaps/data/IobTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/IobTest.kt @@ -23,6 +23,7 @@ class IobTest { Assert.assertTrue(a1 == a1) Assert.assertTrue(a1 == a2) Assert.assertFalse(a1 == b) + @Suppress("SENSELESS_COMPARISON") Assert.assertFalse(a1 == null) Assert.assertFalse(a1 == Any()) } diff --git a/app/src/test/java/info/nightscout/androidaps/data/IobTotalTest.kt b/core/src/test/java/info/nightscout/androidaps/data/IobTotalTest.kt similarity index 98% rename from app/src/test/java/info/nightscout/androidaps/data/IobTotalTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/IobTotalTest.kt index 42b7d96361..ebcf20c4af 100644 --- a/app/src/test/java/info/nightscout/androidaps/data/IobTotalTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/IobTotalTest.kt @@ -6,11 +6,12 @@ import org.junit.Test import org.junit.runner.RunWith import org.powermock.modules.junit4.PowerMockRunner +@Suppress("SpellCheckingInspection") @RunWith(PowerMockRunner::class) class IobTotalTest { var now = DateUtil.now() - @Test fun copytest() { + @Test fun copyTest() { val a = IobTotal(now) a.iob = 10.0 val b = a.copy() diff --git a/app/src/test/java/info/nightscout/androidaps/data/MealDataTest.kt b/core/src/test/java/info/nightscout/androidaps/data/MealDataTest.kt similarity index 100% rename from app/src/test/java/info/nightscout/androidaps/data/MealDataTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/MealDataTest.kt diff --git a/app/src/test/java/info/nightscout/androidaps/data/NonOverlappingIntervalsTest.kt b/core/src/test/java/info/nightscout/androidaps/data/NonOverlappingIntervalsTest.kt similarity index 100% rename from app/src/test/java/info/nightscout/androidaps/data/NonOverlappingIntervalsTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/NonOverlappingIntervalsTest.kt diff --git a/app/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt b/core/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt similarity index 100% rename from app/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt diff --git a/app/src/test/java/info/nightscout/androidaps/data/ProfileIntervalsTest.kt b/core/src/test/java/info/nightscout/androidaps/data/ProfileIntervalsTest.kt similarity index 82% rename from app/src/test/java/info/nightscout/androidaps/data/ProfileIntervalsTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/ProfileIntervalsTest.kt index 06a0239767..422634c5cc 100644 --- a/app/src/test/java/info/nightscout/androidaps/data/ProfileIntervalsTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/ProfileIntervalsTest.kt @@ -1,41 +1,31 @@ package info.nightscout.androidaps.data -import dagger.android.AndroidInjector -import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBaseWithProfile +import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.db.ProfileSwitch -import info.nightscout.androidaps.interfaces.PumpDescription -import info.nightscout.androidaps.logging.AAPSLogger -import info.nightscout.androidaps.plugins.bus.RxBusWrapper -import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin -import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T -import info.nightscout.androidaps.utils.resources.ResourceHelper import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock import org.mockito.Mockito.`when` -import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner import java.util.* @RunWith(PowerMockRunner::class) -@PrepareForTest(VirtualPumpPlugin::class) class ProfileIntervalsTest : TestBaseWithProfile() { - @Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin - + lateinit var testPumpPlugin: TestPumpPlugin private val startDate = DateUtil.now() var list = ProfileIntervals() @Before fun mock() { - `when`(activePluginProvider.activePump).thenReturn(virtualPumpPlugin) - `when`(virtualPumpPlugin.pumpDescription).thenReturn(PumpDescription()) + testPumpPlugin = TestPumpPlugin(profileInjector) + `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin) } + @Test fun doTests() { // create one 10h interval and test value in and out @@ -83,7 +73,7 @@ class ProfileIntervalsTest : TestBaseWithProfile() { someList.add(ProfileSwitch(profileInjector).date(startDate + T.hours(1).msecs()).duration(T.hours(1).mins().toInt()).profileName("6").profile(validProfile)) list.reset() list.add(someList) - Assert.assertEquals(startDate, list[0].date) + Assert.assertEquals(startDate, list[0]?.date) Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).date) Assert.assertEquals(startDate + T.hours(1).msecs(), list.reversedList[0].date) } diff --git a/app/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt b/core/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt similarity index 66% rename from app/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt index 358f417425..045f20520a 100644 --- a/app/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/ProfileTest.kt @@ -1,17 +1,16 @@ package info.nightscout.androidaps.data import info.nightscout.androidaps.Constants -import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBaseWithProfile +import info.nightscout.androidaps.TestPumpPlugin +import info.nightscout.androidaps.core.R import info.nightscout.androidaps.interfaces.PumpDescription -import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.utils.FabricPrivacy import org.json.JSONObject import org.junit.Assert import org.junit.Before import org.junit.Test import org.junit.runner.RunWith -import org.mockito.Mock import org.mockito.Mockito.`when` import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner @@ -21,27 +20,26 @@ import java.util.* /** * Created by mike on 18.03.2018. */ +@Suppress("SpellCheckingInspection") @RunWith(PowerMockRunner::class) -@PrepareForTest(VirtualPumpPlugin::class, FabricPrivacy::class) +@PrepareForTest(FabricPrivacy::class) class ProfileTest : TestBaseWithProfile() { - @Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin + private lateinit var testPumpPlugin: TestPumpPlugin - var okProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - var belowLimitValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.001\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - var notAllignedBasalValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:30\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - var notStartingAtZeroValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:30\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" - var noUnitsValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\"}" - var wrongProfile = "{\"dia\":\"3\",\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var okProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"},{\"time\":\"2:00\",\"value\":\"110\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var belowLimitValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.001\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var notAlignedBasalValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:30\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var notStartingAtZeroValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:30\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" + private var noUnitsValidProfile = "{\"dia\":\"3\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\"}" + private var wrongProfile = "{\"dia\":\"3\",\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"100\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"0.1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4\"}],\"target_high\":[{\"time\":\"00:00\",\"value\":\"5\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}" //String profileStore = "{\"defaultProfile\":\"Default\",\"store\":{\"Default\":" + validProfile + "}}"; - val pumpDescription = PumpDescription() - @Before fun prepare() { - `when`(activePluginProvider.activePump).thenReturn(virtualPumpPlugin) - `when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription) + testPumpPlugin = TestPumpPlugin(profileInjector) + `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin) `when`(resourceHelper.gs(R.string.profile_per_unit)).thenReturn("/U") `when`(resourceHelper.gs(R.string.profile_carbs_per_unit)).thenReturn("g/U") `when`(resourceHelper.gs(R.string.profile_ins_units_per_hour)).thenReturn("U/h") @@ -51,7 +49,7 @@ class ProfileTest : TestBaseWithProfile() { fun doTests() { // Test valid profile - var p: Profile = Profile(profileInjector, JSONObject(okProfile), 100, 0) + var p = Profile(profileInjector, JSONObject(okProfile), 100, 0) Assert.assertEquals(true, p.isValid("Test")) Assert.assertEquals(true, p.log().contains("NS units: mmol")) JSONAssert.assertEquals(okProfile, p.data, false) @@ -141,9 +139,9 @@ class ProfileTest : TestBaseWithProfile() { """.trimIndent(), p.isfList) // Test hour alignment - pumpDescription.is30minBasalRatesCapable = false + testPumpPlugin.pumpDescription.is30minBasalRatesCapable = false //((AAPSMocker.MockedBus) MainApp.bus()).notificationSent = false; - p = Profile(profileInjector, JSONObject(notAllignedBasalValidProfile), 100, 0) + p = Profile(profileInjector, JSONObject(notAlignedBasalValidProfile), 100, 0) p.isValid("Test") //Assert.assertEquals(true, ((AAPSMocker.MockedBus) MainApp.bus()).notificationSent); } diff --git a/app/src/test/java/info/nightscout/androidaps/data/PumpEnactResultTest.kt b/core/src/test/java/info/nightscout/androidaps/data/PumpEnactResultTest.kt similarity index 98% rename from app/src/test/java/info/nightscout/androidaps/data/PumpEnactResultTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/PumpEnactResultTest.kt index e15db553c2..4f40e4c805 100644 --- a/app/src/test/java/info/nightscout/androidaps/data/PumpEnactResultTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/PumpEnactResultTest.kt @@ -3,9 +3,8 @@ package info.nightscout.androidaps.data import android.text.Html import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector -import info.nightscout.androidaps.MainApp -import info.nightscout.androidaps.R import info.nightscout.androidaps.TestBaseWithProfile +import info.nightscout.androidaps.core.R import org.json.JSONObject import org.junit.Assert import org.junit.Before @@ -17,7 +16,7 @@ import org.powermock.modules.junit4.PowerMockRunner import org.skyscreamer.jsonassert.JSONAssert @RunWith(PowerMockRunner::class) -@PrepareForTest(MainApp::class, Html::class) +@PrepareForTest(Html::class) class PumpEnactResultTest : TestBaseWithProfile() { val injector = HasAndroidInjector { diff --git a/app/src/test/java/info/nightscout/androidaps/data/TempTargetTest.kt b/core/src/test/java/info/nightscout/androidaps/data/TempTargetTest.kt similarity index 100% rename from app/src/test/java/info/nightscout/androidaps/data/TempTargetTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/TempTargetTest.kt diff --git a/app/src/test/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfileTest.kt b/core/src/test/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfileTest.kt similarity index 100% rename from app/src/test/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfileTest.kt rename to core/src/test/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfileTest.kt diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/PluginDescriptionTest.kt b/core/src/test/java/info/nightscout/androidaps/interfaces/PluginDescriptionTest.kt similarity index 90% rename from app/src/test/java/info/nightscout/androidaps/interfaces/PluginDescriptionTest.kt rename to core/src/test/java/info/nightscout/androidaps/interfaces/PluginDescriptionTest.kt index 471b890cf1..1e713de26a 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/PluginDescriptionTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/interfaces/PluginDescriptionTest.kt @@ -1,6 +1,6 @@ package info.nightscout.androidaps.interfaces -import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment +import androidx.fragment.app.Fragment import org.junit.Assert import org.junit.Test import org.junit.runner.RunWith @@ -15,8 +15,8 @@ class PluginDescriptionTest { } @Test fun fragmentClassTest() { - val pluginDescription = PluginDescription().fragmentClass(NSProfileFragment::class.java.name) - Assert.assertEquals(NSProfileFragment::class.java.name, pluginDescription.getFragmentClass()) + val pluginDescription = PluginDescription().fragmentClass(Fragment::class.java.name) + Assert.assertEquals(Fragment::class.java.name, pluginDescription.getFragmentClass()) } @Test fun alwaysEnabledTest() { @@ -24,7 +24,7 @@ class PluginDescriptionTest { Assert.assertEquals(true, pluginDescription.alwaysEnabled) } - @Test fun alwayVisibleTest() { + @Test fun alwaysVisibleTest() { val pluginDescription = PluginDescription().alwaysVisible(true) Assert.assertEquals(true, pluginDescription.alwaysVisible) } diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/PumpDescritpionTest.kt b/core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt similarity index 99% rename from app/src/test/java/info/nightscout/androidaps/interfaces/PumpDescritpionTest.kt rename to core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt index fdec787568..96f7edd776 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/PumpDescritpionTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/interfaces/PumpDescriptionTest.kt @@ -9,7 +9,7 @@ import org.junit.Test /** * Created by andy on 5/13/18. */ -class PumpDescritpionTest { +class PumpDescriptionTest { @Test fun setPumpDescription() { val pumpDescription = PumpDescription() diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt b/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt similarity index 91% rename from app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt rename to core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt index 0b922eea35..d591fd3e87 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/aps/loop/APSResultTest.kt @@ -3,12 +3,11 @@ package info.nightscout.androidaps.plugins.aps.loop import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBaseWithProfile +import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.db.TemporaryBasal import info.nightscout.androidaps.interfaces.Constraint -import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.pump.common.defs.PumpType -import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin import info.nightscout.androidaps.utils.JsonHelper.safeGetDouble import info.nightscout.androidaps.utils.sharedPreferences.SP import org.junit.Assert @@ -22,22 +21,21 @@ import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner @RunWith(PowerMockRunner::class) -@PrepareForTest(ConstraintChecker::class, VirtualPumpPlugin::class) +@PrepareForTest(ConstraintChecker::class) class APSResultTest : TestBaseWithProfile() { @Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var sp: SP - @Mock lateinit var virtualPumpPlugin: VirtualPumpPlugin + private lateinit var testPumpPlugin: TestPumpPlugin private val injector = HasAndroidInjector { AndroidInjector { } } private var closedLoopEnabled = Constraint(false) - private val pumpDescription = PumpDescription() @Test fun changeRequestedTest() { - val apsResult = APSResult(HasAndroidInjector { AndroidInjector { Unit } }) + val apsResult = APSResult { AndroidInjector { } } .also { it.aapsLogger = aapsLogger it.constraintChecker = constraintChecker @@ -51,7 +49,7 @@ class APSResultTest : TestBaseWithProfile() { // BASAL RATE IN TEST PROFILE IS 1U/h // **** PERCENT pump **** - pumpDescription.setPumpDescription(PumpType.Cellnovo1) // % based + testPumpPlugin.pumpDescription.setPumpDescription(PumpType.Cellnovo1) // % based apsResult.usePercent(true) // closed loop mode return original request @@ -109,7 +107,7 @@ class APSResultTest : TestBaseWithProfile() { Assert.assertEquals(true, apsResult.isChangeRequested) // **** ABSOLUTE pump **** - virtualPumpPlugin.pumpDescription.setPumpDescription(PumpType.Medtronic_515_715) // U/h based + testPumpPlugin.pumpDescription.setPumpDescription(PumpType.Medtronic_515_715) // U/h based apsResult.usePercent(false) // open loop @@ -158,7 +156,7 @@ class APSResultTest : TestBaseWithProfile() { } @Test fun cloneTest() { - val apsResult = APSResult(HasAndroidInjector { AndroidInjector { Unit } }) + val apsResult = APSResult { AndroidInjector { } } .also { it.aapsLogger = aapsLogger it.constraintChecker = constraintChecker @@ -175,7 +173,7 @@ class APSResultTest : TestBaseWithProfile() { @Test fun jsonTest() { closedLoopEnabled.set(aapsLogger, true) - val apsResult = APSResult(HasAndroidInjector { AndroidInjector { Unit } }) + val apsResult = APSResult { AndroidInjector { } } .also { it.aapsLogger = aapsLogger it.constraintChecker = constraintChecker @@ -193,10 +191,10 @@ class APSResultTest : TestBaseWithProfile() { @Before fun prepare() { + testPumpPlugin = TestPumpPlugin(profileInjector) `when`(constraintChecker.isClosedLoopAllowed()).thenReturn(closedLoopEnabled) - `when`(activePluginProvider.activePump).thenReturn(virtualPumpPlugin) + `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin) `when`(sp.getDouble(ArgumentMatchers.anyInt(), ArgumentMatchers.anyDouble())).thenReturn(30.0) - `when`(virtualPumpPlugin.pumpDescription).thenReturn(pumpDescription) `when`(profileFunction.getProfile()).thenReturn(validProfile) } } \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/ClassicPrefsFormatTest.kt b/core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/ClassicPrefsFormatTest.kt similarity index 85% rename from app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/ClassicPrefsFormatTest.kt rename to core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/ClassicPrefsFormatTest.kt index eb5064e66a..6bf6560187 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/ClassicPrefsFormatTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/ClassicPrefsFormatTest.kt @@ -1,9 +1,6 @@ -package info.nightscout.androidaps.plugins.general.maintenance +package info.nightscout.androidaps.plugins.general.maintenance.formats import info.nightscout.androidaps.TestBase -import info.nightscout.androidaps.plugins.general.maintenance.formats.ClassicPrefsFormat -import info.nightscout.androidaps.plugins.general.maintenance.formats.Prefs -import info.nightscout.androidaps.testing.utils.SingleStringStorage import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP import org.junit.Assert diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/EncryptedPrefsFormatTest.kt b/core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/EncryptedPrefsFormatTest.kt similarity index 98% rename from app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/EncryptedPrefsFormatTest.kt rename to core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/EncryptedPrefsFormatTest.kt index 22674da300..4c27d44072 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/EncryptedPrefsFormatTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/EncryptedPrefsFormatTest.kt @@ -1,8 +1,6 @@ -package info.nightscout.androidaps.plugins.general.maintenance +package info.nightscout.androidaps.plugins.general.maintenance.formats import info.nightscout.androidaps.TestBase -import info.nightscout.androidaps.plugins.general.maintenance.formats.* -import info.nightscout.androidaps.testing.utils.SingleStringStorage import info.nightscout.androidaps.utils.CryptoUtil import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP diff --git a/app/src/test/java/info/nightscout/androidaps/testing/utils/SingleStringStorage.kt b/core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/SingleStringStorage.kt similarity index 84% rename from app/src/test/java/info/nightscout/androidaps/testing/utils/SingleStringStorage.kt rename to core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/SingleStringStorage.kt index 9991779066..715aafff28 100644 --- a/app/src/test/java/info/nightscout/androidaps/testing/utils/SingleStringStorage.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/general/maintenance/formats/SingleStringStorage.kt @@ -1,20 +1,20 @@ -package info.nightscout.androidaps.testing.utils - -import info.nightscout.androidaps.utils.storage.Storage -import java.io.File - -class SingleStringStorage(var contents: String) : Storage { - - override fun getFileContents(file: File): String { - return contents - } - - override fun putFileContents(file: File, contents: String) { - this.contents = contents - } - - override fun toString(): String { - return contents - } - +package info.nightscout.androidaps.plugins.general.maintenance.formats + +import info.nightscout.androidaps.utils.storage.Storage +import java.io.File + +class SingleStringStorage(var contents: String) : Storage { + + override fun getFileContents(file: File): String { + return contents + } + + override fun putFileContents(file: File, contents: String) { + this.contents = contents + } + + override fun toString(): String { + return contents + } + } \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatusTest.kt b/core/src/test/java/info/nightscout/androidaps/plugins/iob/iobCalculator/GlucoseStatusTest.kt similarity index 96% rename from app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatusTest.kt rename to core/src/test/java/info/nightscout/androidaps/plugins/iob/iobCalculator/GlucoseStatusTest.kt index c61d97d6f8..e84d12645f 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatusTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/plugins/iob/iobCalculator/GlucoseStatusTest.kt @@ -1,9 +1,11 @@ -package info.nightscout.androidaps.plugins.iob.iobCobCalculator +package info.nightscout.androidaps.plugins.iob.iobCalculator import dagger.android.AndroidInjector import dagger.android.HasAndroidInjector import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.database.entities.GlucoseValue +import info.nightscout.androidaps.interfaces.IobCobCalculatorInterface +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.T import org.junit.Assert @@ -20,12 +22,13 @@ import java.util.* /** * Created by mike on 26.03.2018. */ +@Suppress("SpellCheckingInspection") @RunWith(PowerMockRunner::class) -@PrepareForTest(IobCobCalculatorPlugin::class, DateUtil::class) +@PrepareForTest(DateUtil::class) class GlucoseStatusTest : TestBase() { @Mock lateinit var dateUtil: DateUtil - @Mock lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin + @Mock lateinit var iobCobCalculatorPlugin: IobCobCalculatorInterface val injector = HasAndroidInjector { AndroidInjector { @@ -80,7 +83,7 @@ class GlucoseStatusTest : TestBase() { Assert.assertEquals(1514766900000L, glucoseStatus.date) // latest date } - @Test fun insuffientDataShouldReturnNull() { + @Test fun insufficientDataShouldReturnNull() { PowerMockito.`when`(iobCobCalculatorPlugin.bgReadings).thenReturn(generateInsufficientBgData()) val glucoseStatus: GlucoseStatus? = GlucoseStatus(injector).glucoseStatusData Assert.assertEquals(null, glucoseStatus) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/pump/common/bolusInfo/DetailedBolusInfoStorageTest.kt b/core/src/test/java/info/nightscout/androidaps/pump/bolusInfo/DetailedBolusInfoStorageTest.kt similarity index 93% rename from app/src/test/java/info/nightscout/androidaps/plugins/pump/common/bolusInfo/DetailedBolusInfoStorageTest.kt rename to core/src/test/java/info/nightscout/androidaps/pump/bolusInfo/DetailedBolusInfoStorageTest.kt index 9f483da250..eb09873b30 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/pump/common/bolusInfo/DetailedBolusInfoStorageTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/pump/bolusInfo/DetailedBolusInfoStorageTest.kt @@ -1,7 +1,8 @@ -package info.nightscout.androidaps.plugins.pump.common.bolusInfo +package info.nightscout.androidaps.pump.bolusInfo import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.data.DetailedBolusInfo +import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Before @@ -16,7 +17,7 @@ class DetailedBolusInfoStorageTest : TestBase() { private val info2 = DetailedBolusInfo() private val info3 = DetailedBolusInfo() - lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage + private lateinit var detailedBolusInfoStorage: DetailedBolusInfoStorage init { info1.date = 1000000 diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/pump/common/utils/DateTimeUtilUTest.java b/core/src/test/java/info/nightscout/androidaps/pump/common/utils/DateTimeUtilUTest.java similarity index 79% rename from app/src/test/java/info/nightscout/androidaps/plugins/pump/common/utils/DateTimeUtilUTest.java rename to core/src/test/java/info/nightscout/androidaps/pump/common/utils/DateTimeUtilUTest.java index d190631ae5..f5557f5eff 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/pump/common/utils/DateTimeUtilUTest.java +++ b/core/src/test/java/info/nightscout/androidaps/pump/common/utils/DateTimeUtilUTest.java @@ -1,10 +1,12 @@ -package info.nightscout.androidaps.plugins.pump.common.utils; +package info.nightscout.androidaps.pump.common.utils; import android.util.Log; import org.junit.Assert; import org.junit.Test; +import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil; + public class DateTimeUtilUTest { @Test diff --git a/app/src/test/java/info/nightscout/androidaps/utils/MidnightTimeTest.java b/core/src/test/java/info/nightscout/androidaps/utils/MidnightTimeTest.java similarity index 100% rename from app/src/test/java/info/nightscout/androidaps/utils/MidnightTimeTest.java rename to core/src/test/java/info/nightscout/androidaps/utils/MidnightTimeTest.java From 2738cf7fcecce9eb08810f36e1db3cdace5421ac Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Sun, 7 Mar 2021 00:46:53 +0000 Subject: [PATCH 07/16] - TBR was incorrectly interpretted for high TBR values --- .../pump/MedtronicPumpHistoryDecoder.java | 14 ++++++++--- .../medtronic/data/dto/TempBasalPair.java | 25 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java index 124b98f880..682d887ff2 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/comm/history/pump/MedtronicPumpHistoryDecoder.java @@ -106,7 +106,7 @@ public class MedtronicPumpHistoryDecoder extends MedtronicHistoryDecoder> 3) == 0); +// TempBasalPair tbr = new TempBasalPair( +// tbrRate.getHead()[0], +// tbrDuration.getHead()[0], +// (ByteUtil.asUINT8(tbrRate.getDatetime()[4]) >> 3) == 0); + + TempBasalPair tbr = new TempBasalPair( + tbrRate.getHead()[0], + tbrRate.getBody()[0], + tbrDuration.getHead()[0], + (ByteUtil.asUINT8(tbrRate.getDatetime()[4]) >> 3) == 0); // System.out.println("TBR: amount=" + tbr.getInsulinRate() + ", duration=" + tbr.getDurationMinutes() // // + " min. Packed: " + tbr.getValue() diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java index 5fa8f3966e..0a5e78427c 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java @@ -1,5 +1,7 @@ package info.nightscout.androidaps.plugins.pump.medtronic.data.dto; +import android.util.Log; + import androidx.annotation.NonNull; import java.util.ArrayList; @@ -38,6 +40,29 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo } + /** + * This constructor is for use with PumpHistoryDecoder + * + * @param rateByte0 + * @param startTimeByte + * @param isPercent + */ + public TempBasalPair(byte rateByte0, byte rateByte1, int startTimeByte, boolean isPercent) { + // int rateInt = ByteUtil.asUINT8(rateByte0); + + if (isPercent) { + this.insulinRate = rateByte0; + } else { + int rateInt2 = ByteUtil.toInt(rateByte1, rateByte0); + int rateInt3 = (rateByte1 & 0x7) << 8 | rateByte0; + this.insulinRate = rateInt2 * 0.025; + Log.d("ddd", "OldRate=" + this.insulinRate + ", NewRate=" + rateInt2 * 0.025 + ", NewRate2=" + + rateInt2 * 0.1 + ", NNNRate=" + rateInt3 * 0.025); + } + this.durationMinutes = startTimeByte * 30; + this.isPercent = isPercent; + } + public TempBasalPair(AAPSLogger aapsLogger, byte[] response) { super(); From 4232679c06e002494cdf6731188b5f385f4f1ed6 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Sun, 7 Mar 2021 00:57:13 +0000 Subject: [PATCH 08/16] - small change (removed unneeded code) --- .../plugins/pump/medtronic/data/dto/TempBasalPair.java | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java index 0a5e78427c..86e5c9bd36 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/dto/TempBasalPair.java @@ -1,7 +1,5 @@ package info.nightscout.androidaps.plugins.pump.medtronic.data.dto; -import android.util.Log; - import androidx.annotation.NonNull; import java.util.ArrayList; @@ -48,16 +46,10 @@ public class TempBasalPair extends info.nightscout.androidaps.plugins.pump.commo * @param isPercent */ public TempBasalPair(byte rateByte0, byte rateByte1, int startTimeByte, boolean isPercent) { - // int rateInt = ByteUtil.asUINT8(rateByte0); - if (isPercent) { this.insulinRate = rateByte0; } else { - int rateInt2 = ByteUtil.toInt(rateByte1, rateByte0); - int rateInt3 = (rateByte1 & 0x7) << 8 | rateByte0; - this.insulinRate = rateInt2 * 0.025; - Log.d("ddd", "OldRate=" + this.insulinRate + ", NewRate=" + rateInt2 * 0.025 + ", NewRate2=" - + rateInt2 * 0.1 + ", NNNRate=" + rateInt3 * 0.025); + this.insulinRate = ByteUtil.toInt(rateByte1, rateByte0) * 0.025; } this.durationMinutes = startTimeByte * 30; this.isPercent = isPercent; From 00ee60ff1e918f8055c7ee74019679e1bda1d4d0 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 7 Mar 2021 11:05:33 +0100 Subject: [PATCH 09/16] Intervals -> kt --- .../nightscout/androidaps/data/Intervals.java | 96 ------------------- .../nightscout/androidaps/data/Intervals.kt | 72 ++++++++++++++ .../data/OverlappingIntervalsTest.kt | 4 +- 3 files changed, 74 insertions(+), 98 deletions(-) delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/Intervals.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/Intervals.kt diff --git a/core/src/main/java/info/nightscout/androidaps/data/Intervals.java b/core/src/main/java/info/nightscout/androidaps/data/Intervals.java deleted file mode 100644 index efb3b76aea..0000000000 --- a/core/src/main/java/info/nightscout/androidaps/data/Intervals.java +++ /dev/null @@ -1,96 +0,0 @@ -package info.nightscout.androidaps.data; - -import androidx.annotation.Nullable; -import androidx.collection.LongSparseArray; - -import java.util.ArrayList; -import java.util.List; - -import info.nightscout.androidaps.interfaces.Interval; - -/** - * Created by mike on 09.05.2017. - */ - -// Zero duration means end of interval - -public abstract class Intervals { - - LongSparseArray rawData; // oldest at index 0 - - public Intervals() { - rawData = new LongSparseArray(); - } - - public synchronized Intervals reset() { - rawData = new LongSparseArray(); - return this; - } - - protected abstract void merge(); - - /** - * The List must be sorted by `T.start()` in ascending order - */ - public synchronized void add(List list) { - for (T interval : list) { - rawData.put(interval.start(), interval); - } - merge(); - } - - public synchronized void add(T interval) { - rawData.put(interval.start(), interval); - merge(); - } - - - public synchronized List getList() { - List list = new ArrayList<>(); - for (int i = 0; i < rawData.size(); i++) - list.add(rawData.valueAt(i)); - return list; - } - - public synchronized List getReversedList() { - List list = new ArrayList<>(); - for (int i = rawData.size() - 1; i >= 0; i--) - list.add(rawData.valueAt(i)); - return list; - } - - protected synchronized int binarySearch(long value) { - int lo = 0; - int hi = rawData.size() - 1; - - while (lo <= hi) { - final int mid = (lo + hi) >>> 1; - final Interval midVal = rawData.valueAt(mid); - - if (midVal.before(value)) { - lo = mid + 1; - } else if (midVal.after(value)) { - hi = mid - 1; - } else if (midVal.match(value)) { - return mid; // value found - } - } - return ~lo; // value not present - } - - public abstract T getValueByInterval(long time); - - public synchronized int size() { - return rawData.size(); - } - - public synchronized T get(int index) { - return rawData.valueAt(index); - } - - public synchronized T getReversed(int index) { - return rawData.valueAt(size() - 1 - index); - } - - -} \ No newline at end of file diff --git a/core/src/main/java/info/nightscout/androidaps/data/Intervals.kt b/core/src/main/java/info/nightscout/androidaps/data/Intervals.kt new file mode 100644 index 0000000000..9145af1748 --- /dev/null +++ b/core/src/main/java/info/nightscout/androidaps/data/Intervals.kt @@ -0,0 +1,72 @@ +package info.nightscout.androidaps.data + +import androidx.collection.LongSparseArray +import info.nightscout.androidaps.interfaces.Interval +import java.util.* + +/** + * Created by mike on 09.05.2017. + */ +// Zero duration means end of interval +abstract class Intervals { + + var rawData: LongSparseArray = LongSparseArray()// oldest at index 0 + + @Synchronized fun reset(): Intervals { + rawData = LongSparseArray() + return this + } + + protected abstract fun merge() + + /** + * The List must be sorted by `T.start()` in ascending order + */ + @Synchronized fun add(list: List) { + for (interval in list) { + rawData.put(interval.start(), interval) + } + merge() + } + + @Synchronized fun add(interval: T) { + rawData.put(interval.start(), interval) + merge() + } + + @get:Synchronized val list: List + get() { + val list: MutableList = ArrayList() + for (i in 0 until rawData.size()) list.add(rawData.valueAt(i)) + return list + } + @get:Synchronized val reversedList: List + get() { + val list: MutableList = ArrayList() + for (i in rawData.size() - 1 downTo 0) list.add(rawData.valueAt(i)) + return list + } + + @Synchronized protected fun binarySearch(value: Long): Int { + var lo = 0 + var hi = rawData.size() - 1 + while (lo <= hi) { + val mid = lo + hi ushr 1 + val midVal: Interval = rawData.valueAt(mid) + when { + midVal.before(value) -> lo = mid + 1 + midVal.after(value) -> hi = mid - 1 + midVal.match(value) -> return mid // value found + } + } + return lo.inv() // value not present + } + + abstract fun getValueByInterval(time: Long): T? + + @Synchronized fun size(): Int = rawData.size() + + @Synchronized operator fun get(index: Int): T? = rawData.valueAt(index) + + @Synchronized fun getReversed(index: Int): T? = rawData.valueAt(size() - 1 - index) +} \ No newline at end of file diff --git a/core/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt b/core/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt index f3e3104ca8..71e469d682 100644 --- a/core/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt +++ b/core/src/test/java/info/nightscout/androidaps/data/OverlappingIntervalsTest.kt @@ -52,8 +52,8 @@ class OverlappingIntervalsTest { someList.add(TempTargetTest().date(startDate + T.hours(1).msecs()).duration(T.hours(1).mins()).low(100.0).high(100.0)) list.reset() list.add(someList) - Assert.assertEquals(startDate, list[0].data.timestamp) - Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0).data.timestamp) + Assert.assertEquals(startDate, list[0]?.data?.timestamp) + Assert.assertEquals(startDate + T.hours(1).msecs(), list.getReversed(0)?.data?.timestamp) Assert.assertEquals(startDate + T.hours(1).msecs(), list.reversedList[0].data.timestamp) } } \ No newline at end of file From 2ea423c70482071a1f3ee2d439e9e2fb7ff08d1c Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 7 Mar 2021 13:31:11 +0100 Subject: [PATCH 10/16] PumpEnactResult -> kt --- .idea/codeStyles/Project.xml | 16 ++ .../androidaps/plugins/aps/loop/LoopPlugin.kt | 20 +- .../androidaps/queue/CommandQueue.kt | 6 +- .../interfaces/ConstraintsCheckerTest.kt | 4 + .../SmsCommunicatorPluginTest.kt | 1 - .../androidaps/queue/CommandQueueTest.kt | 2 + .../automation/actions/ActionAlarmTest.kt | 1 - .../actions/ActionNotificationTest.kt | 1 - .../automation/actions/ActionsTestBase.kt | 1 - .../plugins/pump/combo/ComboPlugin.java | 35 ++- .../plugins/pump/combo/ComboPluginTest.kt | 5 + .../nightscout/androidaps/data/Intervals.kt | 2 +- .../androidaps/data/PumpEnactResult.java | 201 ------------------ .../androidaps/data/PumpEnactResult.kt | 165 ++++++++++++++ .../plugins/general/nsclient/NSUpload.java | 11 +- .../pump/common/PumpPluginAbstract.java | 6 +- .../androidaps/data/PumpEnactResultTest.kt | 1 - .../danaRKorean/DanaRKoreanPlugin.java | 66 ++---- .../androidaps/danaRv2/DanaRv2Plugin.java | 97 +++------ .../services/DanaRv2ExecutionService.java | 2 +- .../androidaps/danar/AbstractDanaRPlugin.java | 97 ++++----- .../androidaps/danar/DanaRPlugin.java | 66 ++---- .../AbstractDanaRExecutionService.java | 3 +- .../pump/insight/LocalInsightPlugin.java | 171 +++++++-------- .../pump/medtronic/MedtronicPumpPlugin.java | 31 ++- .../omnipod/eros/OmnipodErosPumpPlugin.java | 22 +- .../eros/manager/AapsOmnipodErosManager.java | 6 +- .../eros/OmnipodErosPumpPluginTest.java | 52 ++--- 28 files changed, 478 insertions(+), 613 deletions(-) delete mode 100644 core/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.java create mode 100644 core/src/main/java/info/nightscout/androidaps/data/PumpEnactResult.kt diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index ff53f4004f..3542887fac 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -2,6 +2,22 @@