Merge branch 'meallink' into meallink_VWU_v2

This commit is contained in:
Philoul 2021-04-10 20:44:08 +02:00
commit 62443f6738
81 changed files with 343 additions and 261 deletions

View file

@ -79,7 +79,7 @@ open class AppModule {
@Binds fun bindCommandQueueProvider(commandQueue: CommandQueue): CommandQueueProvider
@Binds fun bindConfigInterface(config: Config): ConfigInterface
@Binds fun bindConfigBuilderInterface(configBuilderPlugin: ConfigBuilderPlugin): ConfigBuilderInterface
@Binds fun bindTreatmentInterface(treatmentsPlugin: TreatmentsPlugin): TreatmentsInterface
@Binds fun bindTreatmentsInterface(treatmentsPlugin: TreatmentsPlugin): TreatmentsInterface
@Binds fun bindDatabaseHelperInterface(databaseHelperProvider: DatabaseHelperProvider): DatabaseHelperInterface
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolder): NotificationHolderInterface
@Binds fun bindImportExportPrefsInterface(importExportPrefs: ImportExportPrefs): ImportExportPrefsInterface

View file

@ -30,7 +30,8 @@ class ConfigBuilderPlugin @Inject constructor(
private val sp: SP,
private val rxBus: RxBusWrapper,
private val activePlugin: ActivePluginProvider,
private val uel: UserEntryLogger
private val uel: UserEntryLogger,
private val pumpSync: PumpSync
) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(ConfigBuilderFragment::class.java.name)
@ -141,14 +142,16 @@ class ConfigBuilderPlugin @Inject constructor(
val allowHardwarePump = sp.getBoolean("allow_hardware_pump", false)
if (allowHardwarePump || activity == null) {
performPluginSwitch(changedPlugin, newState, type)
pumpSync.connectNewPump()
} else {
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.allow_hardware_pump_text), Runnable {
OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.allow_hardware_pump_text), {
performPluginSwitch(changedPlugin, newState, type)
pumpSync.connectNewPump()
sp.putBoolean("allow_hardware_pump", true)
uel.log(Action.HW_PUMP_ALLOWED, Sources.ConfigBuilder,
ValueWithUnit.StringResource(changedPlugin.pluginDescription.pluginName))
aapsLogger.debug(LTag.PUMP, "First time HW pump allowed!")
}, Runnable {
}, {
rxBus.send(EventConfigBuilderUpdateGui())
aapsLogger.debug(LTag.PUMP, "User does not allow switching to HW pump!")
})

View file

@ -15,6 +15,7 @@ import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.interfaces.DataSyncSelector
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ImportExportPrefsInterface
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -39,6 +40,7 @@ class MaintenanceFragment : DaggerFragment() {
@Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var uel: UserEntryLogger
@Inject lateinit var dataSyncSelector: DataSyncSelector
@Inject lateinit var pumpSync: PumpSync
private val compositeDisposable = CompositeDisposable()
@ -68,6 +70,7 @@ class MaintenanceFragment : DaggerFragment() {
databaseHelper.resetDatabases()
repository.clearDatabases()
dataSyncSelector.resetToNextFullSync()
pumpSync.connectNewPump()
}
.subscribeOn(aapsSchedulers.io)
.observeOn(aapsSchedulers.main)

View file

@ -53,7 +53,7 @@ import java.util.*
@PrepareForTest(
ConfigBuilderPlugin::class, ConstraintChecker::class, SP::class, Context::class,
OpenAPSAMAPlugin::class, OpenAPSSMBPlugin::class, TreatmentsPlugin::class, TreatmentService::class,
VirtualPumpPlugin::class, DetailedBolusInfoStorage::class, GlimpPlugin::class, Profiler::class,
VirtualPumpPlugin::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class, GlimpPlugin::class, Profiler::class,
UserEntryLogger::class, IobCobCalculatorPlugin::class, LoggerUtils::class, AppRepository::class)
class ConstraintsCheckerTest : TestBaseWithProfile() {

View file

@ -1,15 +1,12 @@
package info.nightscout.androidaps.plugins.configBuilder
import dagger.Lazy
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.CommandQueueProvider
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.UserEntryLogger
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.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Before
@ -23,22 +20,15 @@ import org.powermock.modules.junit4.PowerMockRunner
@PrepareForTest(UserEntryLogger::class)
class ConfigBuilderPluginTest : TestBase() {
@Mock lateinit var virtualPumpPlugin: Lazy<VirtualPumpPlugin>
@Mock lateinit var treatmentsPlugin: Lazy<TreatmentsPlugin>
@Mock lateinit var sp: SP
@Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var commandQueue: CommandQueueProvider
@Mock lateinit var activePlugin: ActivePluginProvider
@Mock lateinit var uel: UserEntryLogger
@Mock lateinit var pumpSync: PumpSync
private lateinit var configBuilderPlugin: ConfigBuilderPlugin
val injector = HasAndroidInjector {
AndroidInjector {
}
}
val injector = HasAndroidInjector { AndroidInjector { } }
@Test
fun dummy() {
@ -47,6 +37,6 @@ class ConfigBuilderPluginTest : TestBase() {
@Before
fun prepareMock() {
configBuilderPlugin = ConfigBuilderPlugin(injector, aapsLogger, resourceHelper, sp, RxBusWrapper(aapsSchedulers), activePlugin, uel)
configBuilderPlugin = ConfigBuilderPlugin(injector, aapsLogger, resourceHelper, sp, RxBusWrapper(aapsSchedulers), activePlugin, uel, pumpSync)
}
}

View file

@ -139,17 +139,17 @@ class SmsCommunicatorPluginTest : TestBaseWithProfile() {
null
}.`when`(commandQueue).bolus(anyObject(), ArgumentMatchers.any(Callback::class.java))
Mockito.doAnswer { invocation: InvocationOnMock ->
val callback = invocation.getArgument<Callback>(4)
val callback = invocation.getArgument<Callback>(5)
callback.result = PumpEnactResult(injector).success(true).isPercent(true).percent(invocation.getArgument(0)).duration(invocation.getArgument(1))
callback.run()
null
}.`when`(commandQueue).tempBasalPercent(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyBoolean(), anyObject(), ArgumentMatchers.any(PumpSync.TemporaryBasalType::class.java), ArgumentMatchers.any(Callback::class.java))
}.`when`(commandQueue).tempBasalPercent(ArgumentMatchers.anyInt(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyBoolean(), anyObject(), anyObject(), ArgumentMatchers.any(Callback::class.java))
Mockito.doAnswer { invocation: InvocationOnMock ->
val callback = invocation.getArgument<Callback>(4)
val callback = invocation.getArgument<Callback>(5)
callback.result = PumpEnactResult(injector).success(true).isPercent(false).absolute(invocation.getArgument(0)).duration(invocation.getArgument(1))
callback.run()
null
}.`when`(commandQueue).tempBasalAbsolute(ArgumentMatchers.anyDouble(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyBoolean(), anyObject(), ArgumentMatchers.any(PumpSync.TemporaryBasalType::class.java), ArgumentMatchers.any(Callback::class.java))
}.`when`(commandQueue).tempBasalAbsolute(ArgumentMatchers.anyDouble(), ArgumentMatchers.anyInt(), ArgumentMatchers.anyBoolean(), anyObject(), anyObject(), ArgumentMatchers.any(Callback::class.java))
Mockito.doAnswer { invocation: InvocationOnMock ->
val callback = invocation.getArgument<Callback>(2)
callback.result = PumpEnactResult(injector).success(true).isPercent(false).absolute(invocation.getArgument(0)).duration(invocation.getArgument(1))

View file

@ -121,7 +121,7 @@ class IobCobCalculatorPluginTest : TestBase() {
}
@Test
fun createBucketedData5minTest() {
fun createBucketedData5minTest1() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
// Super data should not be touched
@ -205,6 +205,11 @@ class IobCobCalculatorPluginTest : TestBase() {
Assert.assertEquals(90.0, iobCobCalculatorPlugin.bucketedData!![1].value, 1.0)
Assert.assertEquals(50.0, iobCobCalculatorPlugin.bucketedData!![5].value, 1.0)
Assert.assertEquals(40.0, iobCobCalculatorPlugin.bucketedData!![6].value, 1.0)
}
@Test
fun createBucketedData5minTest2() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList()
//bucketed data should be null if no bg data available
iobCobCalculatorPlugin.bgReadings = ArrayList()

View file

@ -48,6 +48,8 @@ class TreatmentsPluginTest : TestBaseWithProfile() {
}
}
}
@Test fun dumy() {}
/*
private lateinit var insulinOrefRapidActingPlugin: InsulinOrefRapidActingPlugin
private lateinit var sot: TreatmentsPlugin

View file

@ -14,7 +14,6 @@ import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.ActivePluginProvider
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.TreatmentsInterface
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseTriggerDialog
@ -26,10 +25,8 @@ import info.nightscout.androidaps.services.LastLocationDataContainer
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONException
import org.json.JSONObject
import javax.inject.Inject
import kotlin.reflect.full.primaryConstructor
abstract class Trigger(val injector: HasAndroidInjector) {
@ -50,7 +47,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
}
abstract fun shouldRun(): Boolean
abstract fun toJSON(): String
abstract fun dataJSON(): JSONObject
abstract fun fromJSON(data: String): Trigger
abstract fun friendlyName(): Int
@ -77,23 +74,56 @@ abstract class Trigger(val injector: HasAndroidInjector) {
root.addView(title)
}
fun toJSON(): String =
JSONObject()
.put("type", this::class.java.simpleName)
.put("data", dataJSON())
.toString()
fun instantiate(obj: JSONObject): Trigger? {
try {
val type = obj.getString("type")
val data = obj.getJSONObject("data")
val clazz = Class.forName(type).kotlin
return (clazz.primaryConstructor?.call(injector) as Trigger).fromJSON(data?.toString()
?: "")
} catch (e: ClassNotFoundException) {
aapsLogger.error("Unhandled exception", e)
} catch (e: InstantiationException) {
aapsLogger.error("Unhandled exception", e)
} catch (e: IllegalAccessException) {
aapsLogger.error("Unhandled exception", e)
} catch (e: JSONException) {
aapsLogger.error("Unhandled exception", e)
val type = obj.getString("type")
val data = obj.getJSONObject("data")
//val clazz = Class.forName(type).kotlin
//return (clazz.primaryConstructor?.call(injector) as Trigger).fromJSON(data?.toString() ?: "")
return when (type) {
TriggerAutosensValue::class.java.name, // backward compatibility
TriggerAutosensValue::class.java.simpleName -> TriggerAutosensValue(injector).fromJSON(data?.toString() ?: "")
TriggerBg::class.java.name,
TriggerBg::class.java.simpleName -> TriggerBg(injector).fromJSON(data?.toString() ?: "")
TriggerBolusAgo::class.java.name,
TriggerBolusAgo::class.java.simpleName -> TriggerBolusAgo(injector).fromJSON(data?.toString() ?: "")
TriggerBTDevice::class.java.name,
TriggerBTDevice::class.java.simpleName -> TriggerBTDevice(injector).fromJSON(data?.toString() ?: "")
TriggerIob::class.java.name,
TriggerIob::class.java.simpleName -> TriggerIob(injector).fromJSON(data?.toString() ?: "")
TriggerCOB::class.java.name,
TriggerCOB::class.java.simpleName -> TriggerCOB(injector).fromJSON(data?.toString() ?: "")
TriggerConnector::class.java.name,
TriggerConnector::class.java.simpleName -> TriggerConnector(injector).fromJSON(data?.toString() ?: "")
TriggerDelta::class.java.name,
TriggerDelta::class.java.simpleName -> TriggerDelta(injector).fromJSON(data?.toString() ?: "")
TriggerDummy::class.java.name,
TriggerDummy::class.java.simpleName -> TriggerDummy(injector).fromJSON(data?.toString() ?: "")
TriggerIob::class.java.name,
TriggerIob::class.java.simpleName -> TriggerIob(injector).fromJSON(data?.toString() ?: "")
TriggerLocation::class.java.name,
TriggerLocation::class.java.simpleName -> TriggerLocation(injector).fromJSON(data?.toString() ?: "")
TriggerProfilePercent::class.java.name,
TriggerProfilePercent::class.java.simpleName -> TriggerProfilePercent(injector).fromJSON(data?.toString() ?: "")
TriggerPumpLastConnection::class.java.name,
TriggerPumpLastConnection::class.java.simpleName -> TriggerPumpLastConnection(injector).fromJSON(data?.toString() ?: "")
TriggerRecurringTime::class.java.name,
TriggerRecurringTime::class.java.simpleName -> TriggerRecurringTime(injector).fromJSON(data?.toString() ?: "")
TriggerTempTarget::class.java.name,
TriggerTempTarget::class.java.simpleName -> TriggerTempTarget(injector).fromJSON(data?.toString() ?: "")
TriggerTime::class.java.name,
TriggerTime::class.java.simpleName -> TriggerTime(injector).fromJSON(data?.toString() ?: "")
TriggerTimeRange::class.java.name,
TriggerTimeRange::class.java.simpleName -> TriggerTimeRange(injector).fromJSON(data?.toString() ?: "")
TriggerWifiSsid::class.java.name,
TriggerWifiSsid::class.java.simpleName -> TriggerWifiSsid(injector).fromJSON(data?.toString() ?: "")
else -> throw ClassNotFoundException(type)
}
return null
}
fun createAddButton(context: Context, trigger: TriggerConnector): ImageButton {

View file

@ -46,15 +46,10 @@ class TriggerAutosensValue(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("value", autosens.value)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -39,15 +39,10 @@ class TriggerBTDevice(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
@Synchronized override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("comparator", comparator.value.toString())
.put("name", btDevice.value)
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -63,16 +63,11 @@ class TriggerBg(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("bg", bg.value)
.put("comparator", comparator.value.toString())
.put("units", bg.units)
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -56,15 +56,10 @@ class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("minutesAgo", minutesAgo.value)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -16,6 +16,7 @@ import org.json.JSONObject
import java.text.DecimalFormat
class TriggerCOB(injector: HasAndroidInjector) : Trigger(injector) {
private val minValue = 0
private val maxValue = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48)
var cob: InputDouble = InputDouble(0.0, minValue.toDouble(), maxValue.toDouble(), 1.0, DecimalFormat("1"))
@ -26,12 +27,12 @@ class TriggerCOB(injector: HasAndroidInjector) : Trigger(injector) {
comparator = Comparator(resourceHelper, triggerCOB.comparator.value)
}
fun setValue(value:Double) : TriggerCOB {
fun setValue(value: Double): TriggerCOB {
cob.value = value
return this
}
fun comparator(comparator: Comparator.Compare) : TriggerCOB {
fun comparator(comparator: Comparator.Compare): TriggerCOB {
this.comparator.value = comparator
return this
}
@ -55,15 +56,10 @@ class TriggerCOB(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
@Synchronized override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("carbs", cob.value)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -19,6 +19,7 @@ import org.json.JSONObject
import java.util.*
class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
var list: MutableList<Trigger> = ArrayList()
private var connectorType: Type = Type.AND
@ -40,6 +41,7 @@ class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
}
companion object {
fun labels(resourceHelper: ResourceHelper): List<String> {
val list: MutableList<String> = ArrayList()
for (t in values()) {
@ -79,16 +81,12 @@ class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
return result
}
@Synchronized override fun toJSON(): String {
override fun dataJSON(): JSONObject {
val array = JSONArray()
for (t in list) array.put(t.toJSON())
val data = JSONObject()
return JSONObject()
.put("connectorType", connectorType.toString())
.put("triggerList", array)
return JSONObject()
.put("type", TriggerConnector::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {

View file

@ -13,7 +13,6 @@ import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
import java.text.DecimalFormat
@ -25,6 +24,7 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
var comparator: Comparator = Comparator(resourceHelper)
companion object {
private const val MMOL_MAX = 4.0
private const val MGDL_MAX = 72.0
}
@ -85,17 +85,12 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("value", delta.value)
.put("units", units)
.put("deltaType", delta.deltaType)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.automation.triggers
import com.google.common.base.Optional
import dagger.android.HasAndroidInjector
import org.json.JSONObject
// Used for instantiation of other triggers only
class TriggerDummy(injector: HasAndroidInjector, val shouldRun: Boolean = false) : Trigger(injector) {
@ -10,7 +11,7 @@ class TriggerDummy(injector: HasAndroidInjector, val shouldRun: Boolean = false)
return shouldRun
}
override fun toJSON(): String {
override fun dataJSON(): JSONObject {
throw NotImplementedError("An operation is not implemented")
}

View file

@ -44,15 +44,10 @@ class TriggerIob(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
@Synchronized override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("insulin", insulin.value)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -12,6 +12,7 @@ import org.json.JSONObject
import java.text.DecimalFormat
class TriggerLocation(injector: HasAndroidInjector) : Trigger(injector) {
var latitude = InputDouble(0.0, -90.0, +90.0, 0.000001, DecimalFormat("0.000000"))
var longitude = InputDouble(0.0, -180.0, +180.0, 0.000001, DecimalFormat("0.000000"))
var distance = InputDouble(200.0, 0.0, 100000.0, 10.0, DecimalFormat("0"))
@ -56,18 +57,13 @@ class TriggerLocation(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("latitude", latitude.value)
.put("longitude", longitude.value)
.put("distance", distance.value)
.put("name", name.value)
.put("mode", modeSelected.value)
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -14,11 +14,12 @@ import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
class TriggerProfilePercent(injector: HasAndroidInjector) : Trigger(injector) {
var pct = InputPercent()
var comparator = Comparator(resourceHelper)
constructor(injector: HasAndroidInjector, value: Double, compare: Comparator.Compare) : this(injector) {
pct = InputPercent( value)
pct = InputPercent(value)
comparator = Comparator(resourceHelper, compare)
}
@ -55,15 +56,10 @@ class TriggerProfilePercent(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
@Synchronized override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("percentage", pct.value)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -16,6 +16,7 @@ import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import org.json.JSONObject
class TriggerPumpLastConnection(injector: HasAndroidInjector) : Trigger(injector) {
var minutesAgo = InputDuration()
var comparator = Comparator(resourceHelper)
@ -56,15 +57,10 @@ class TriggerPumpLastConnection(injector: HasAndroidInjector) : Trigger(injector
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("minutesAgo", minutesAgo.value)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -44,16 +44,13 @@ class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
override fun dataJSON(): JSONObject {
val data = JSONObject()
.put("time", time.value)
for (i in days.weekdays.indices) {
data.put(InputWeekDay.DayOfWeek.values()[i].name, days.weekdays[i])
}
return JSONObject()
.put("type", TriggerRecurringTime::class.java.name)
.put("data", data)
.toString()
return data
}
override fun fromJSON(data: String): Trigger {

View file

@ -43,14 +43,9 @@ class TriggerTempTarget(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", TriggerTempTarget::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -41,14 +41,9 @@ class TriggerTime(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("runAt", time.value)
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val o = JSONObject(data)

View file

@ -50,15 +50,10 @@ class TriggerTimeRange(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("start", range.start)
.put("end", range.end)
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): TriggerTimeRange {
val o = JSONObject(data)

View file

@ -16,12 +16,14 @@ import org.json.JSONObject
import javax.inject.Inject
class TriggerWifiSsid(injector: HasAndroidInjector) : Trigger(injector) {
@Inject lateinit var receiverStatusStore: ReceiverStatusStore
var ssid = InputString()
var comparator = Comparator(resourceHelper)
@Suppress("unused") constructor(injector: HasAndroidInjector, ssid: String, compare: Comparator.Compare) : this(injector) {
@Suppress("unused")
constructor(injector: HasAndroidInjector, ssid: String, compare: Comparator.Compare) : this(injector) {
this.ssid = InputString(ssid)
comparator = Comparator(resourceHelper, compare)
}
@ -55,15 +57,10 @@ class TriggerWifiSsid(injector: HasAndroidInjector) : Trigger(injector) {
return false
}
override fun toJSON(): String {
val data = JSONObject()
override fun dataJSON(): JSONObject =
JSONObject()
.put("ssid", ssid.value)
.put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)

View file

@ -48,7 +48,7 @@ class AutomationEventTest : TestBase() {
event.addAction(ActionLoopEnable(injector))
// export to json
val eventJsonExpected = "{\"autoRemove\":false,\"readOnly\":false,\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\",\"title\":\"Test\",\"systemAction\":false,\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}"
val eventJsonExpected = "{\"autoRemove\":false,\"readOnly\":false,\"trigger\":\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"data\\\\\\\":{\\\\\\\"connectorType\\\\\\\":\\\\\\\"AND\\\\\\\",\\\\\\\"triggerList\\\\\\\":[]},\\\\\\\"type\\\\\\\":\\\\\\\"TriggerConnector\\\\\\\"}\\\"]},\\\"type\\\":\\\"TriggerConnector\\\"}\",\"title\":\"Test\",\"systemAction\":false,\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionLoopEnable\\\"}\"],\"enabled\":true}"
Assert.assertEquals(eventJsonExpected, event.toJSON())
// clone

View file

@ -8,6 +8,7 @@ import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.*
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
import info.nightscout.androidaps.utils.resources.ResourceHelper
@ -17,7 +18,7 @@ import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.powermock.core.classloader.annotations.PrepareForTest
@PrepareForTest(RxBusWrapper::class, ActionsTestBase.TestLoopPlugin::class)
@PrepareForTest(RxBusWrapper::class, ActionsTestBase.TestLoopPlugin::class, UserEntryLogger::class)
open class ActionsTestBase : TestBaseWithProfile() {
open class TestLoopPlugin(
@ -29,7 +30,7 @@ open class ActionsTestBase : TestBaseWithProfile() {
pluginDescription, aapsLogger, resourceHelper, injector
), LoopInterface {
var suspended = false
private var suspended = false
override var lastRun: LoopInterface.LastRun? = LoopInterface.LastRun()
override val isSuspended: Boolean = suspended
override fun suspendTo(endTime: Long) {}
@ -44,6 +45,7 @@ open class ActionsTestBase : TestBaseWithProfile() {
@Mock lateinit var profilePlugin: ProfileInterface
@Mock lateinit var smsCommunicatorPlugin: SmsCommunicatorInterface
@Mock lateinit var loopPlugin: TestLoopPlugin
@Mock lateinit var uel: UserEntryLogger
private val pluginDescription = PluginDescription()
lateinit var testPumpPlugin: TestPumpPlugin
@ -55,6 +57,7 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.resourceHelper = resourceHelper
it.dateUtil = dateUtil
it.repository = repository
it.uel = uel
}
if (it is ActionStartTempTarget) {
it.aapsLogger = aapsLogger
@ -62,6 +65,7 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.activePlugin = activePlugin
it.repository = repository
it.profileFunction = profileFunction
it.uel = uel
}
if (it is ActionSendSMS) {
it.aapsLogger = aapsLogger
@ -73,10 +77,12 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.resourceHelper = resourceHelper
it.activePlugin = activePlugin
it.profileFunction = profileFunction
it.uel = uel
}
if (it is ActionProfileSwitchPercent) {
it.resourceHelper = resourceHelper
it.activePlugin = activePlugin
it.uel = uel
}
if (it is ActionNotification) {
it.resourceHelper = resourceHelper
@ -86,18 +92,21 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper
it.rxBus = rxBus
it.uel = uel
}
if (it is ActionLoopResume) {
it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper
it.configBuilderPlugin = configBuilderPlugin
it.rxBus = rxBus
it.uel = uel
}
if (it is ActionLoopEnable) {
it.loopPlugin = loopPlugin
it.resourceHelper = resourceHelper
it.configBuilderPlugin = configBuilderPlugin
it.rxBus = rxBus
it.uel = uel
}
if (it is ActionLoopDisable) {
it.loopPlugin = loopPlugin
@ -105,6 +114,7 @@ open class ActionsTestBase : TestBaseWithProfile() {
it.configBuilderPlugin = configBuilderPlugin
it.commandQueue = commandQueue
it.rxBus = rxBus
it.uel = uel
}
if (it is PumpEnactResult) {
it.resourceHelper = resourceHelper

View file

@ -3,34 +3,15 @@ package info.nightscout.androidaps.plugins.general.automation.triggers
import com.google.common.base.Optional
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import org.json.JSONObject
class DummyTrigger(var result: Boolean) : Trigger(HasAndroidInjector { AndroidInjector { } }) {
override fun shouldRun(): Boolean {
return result
}
override fun toJSON(): String {
return ""
}
override fun fromJSON(data: String): Trigger {
return DummyTrigger(result)
}
override fun friendlyName(): Int {
return 0
}
override fun friendlyDescription(): String {
return " "
}
override fun icon(): Optional<Int?> {
return Optional.absent()
}
override fun duplicate(): Trigger {
return DummyTrigger(result)
}
override fun shouldRun(): Boolean = result
override fun dataJSON(): JSONObject = JSONObject()
override fun fromJSON(data: String): Trigger = DummyTrigger(result)
override fun friendlyName(): Int = 0
override fun friendlyDescription(): String = " "
override fun icon(): Optional<Int?> = Optional.absent()
override fun duplicate(): Trigger = DummyTrigger(result)
}

View file

@ -88,7 +88,7 @@ class TriggerAutosensValueTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var asJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"value\":410},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerAutosensValue\"}"
private var asJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"value\":410},\"type\":\"TriggerAutosensValue\"}"
@Test
fun toJSONTest() {

View file

@ -15,7 +15,7 @@ class TriggerBTDeviceTest : TriggerTestBase() {
var now = 1514766900000L
private var someName = "Headset"
private var btJson = "{\"data\":{\"comparator\":\"ON_CONNECT\",\"name\":\"Headset\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBTDevice\"}"
private var btJson = "{\"data\":{\"comparator\":\"ON_CONNECT\",\"name\":\"Headset\"},\"type\":\"TriggerBTDevice\"}"
@Test fun shouldRun() {
@Suppress("UNUSED_VARIABLE")

View file

@ -69,7 +69,7 @@ class TriggerBgTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"bg\":4.1,\"units\":\"mmol\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBg\"}"
private var bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"bg\":4.1,\"units\":\"mmol\"},\"type\":\"TriggerBg\"}"
@Test
fun toJSONTest() {

View file

@ -77,7 +77,7 @@ class TriggerBolusAgoTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var lbJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"minutesAgo\":410},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBolusAgo\"}"
private var lbJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"minutesAgo\":410},\"type\":\"TriggerBolusAgo\"}"
@Test fun toJSONTest() {
val t: TriggerBolusAgo = TriggerBolusAgo(injector).setValue(410).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(lbJson, t.toJSON())

View file

@ -54,7 +54,7 @@ class TriggerCOBTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"carbs\":4},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerCOB\"}"
private var bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"carbs\":4},\"type\":\"TriggerCOB\"}"
@Test fun toJSONTest() {
val t: TriggerCOB = TriggerCOB(injector).setValue(4.0).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(bgJson, t.toJSON())

View file

@ -77,7 +77,7 @@ class TriggerConnectorTest : TriggerTestBase() {
}
companion object {
const val empty = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[]},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\"}"
const val oneItem = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[]},\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\"]},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\"}"
const val empty = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[]},\"type\":\"TriggerConnector\"}"
const val oneItem = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[\"{\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[]},\\\"type\\\":\\\"TriggerConnector\\\"}\"]},\"type\":\"TriggerConnector\"}"
}
}

View file

@ -72,7 +72,7 @@ class TriggerDeltaTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var deltaJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"deltaType\":\"DELTA\",\"units\":\"mg/dl\",\"value\":4.1},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDelta\"}"
private var deltaJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"deltaType\":\"DELTA\",\"units\":\"mg/dl\",\"value\":4.1},\"type\":\"TriggerDelta\"}"
@Test
fun toJSONTest() {

View file

@ -30,7 +30,7 @@ class TriggerIobTest : TriggerTestBase() {
}
@Test fun shouldRunTest() {
`when`(iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(ArgumentMatchers.anyLong(), ArgumentMatchers.any(Profile::class.java))).thenReturn(generateIobRecordData())
`when`(iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(ArgumentMatchers.anyLong(), anyObject())).thenReturn(generateIobRecordData())
var t: TriggerIob = TriggerIob(injector).setValue(1.1).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertFalse(t.shouldRun())
t = TriggerIob(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL)
@ -57,7 +57,7 @@ class TriggerIobTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"insulin\":4.1},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerIob\"}"
private var bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"insulin\":4.1},\"type\":\"TriggerIob\"}"
@Test fun toJSONTest() {
val t: TriggerIob = TriggerIob(injector).setValue(4.1).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(bgJson, t.toJSON())

View file

@ -73,7 +73,7 @@ class TriggerLocationTest : TriggerTestBase() {
// Currently unavailable due to problems with Location mocking
}
private var locationJson = "{\"data\":{\"mode\":\"OUTSIDE\",\"distance\":2,\"latitude\":213,\"name\":\"\",\"longitude\":212},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerLocation\"}"
private var locationJson = "{\"data\":{\"mode\":\"OUTSIDE\",\"distance\":2,\"latitude\":213,\"name\":\"\",\"longitude\":212},\"type\":\"TriggerLocation\"}"
@Test fun toJSONTest() {
val t = TriggerLocation(injector)
t.latitude.setValue(213.0)

View file

@ -55,7 +55,7 @@ class TriggerProfilePercentTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private val bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"percentage\":110},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerProfilePercent\"}"
private val bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"percentage\":110},\"type\":\"TriggerProfilePercent\"}"
@Test fun toJSONTest() {
val t: TriggerProfilePercent = TriggerProfilePercent(injector).setValue(110.0).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(bgJson, t.toJSON())

View file

@ -53,7 +53,7 @@ class TriggerPumpLastConnectionTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var lbJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"minutesAgo\":410},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerPumpLastConnection\"}"
private var lbJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"minutesAgo\":410},\"type\":\"TriggerPumpLastConnection\"}"
@Test fun toJSONTest() {
val t: TriggerPumpLastConnection = TriggerPumpLastConnection(injector).setValue(410).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(lbJson, t.toJSON())

View file

@ -35,7 +35,7 @@ class TriggerRecurringTimeTest : TriggerTestBase() {
Assert.assertTrue(t.shouldRun())
}
private var timeJson = "{\"data\":{\"WEDNESDAY\":false,\"MONDAY\":false,\"THURSDAY\":false,\"SUNDAY\":false,\"TUESDAY\":false,\"FRIDAY\":false,\"SATURDAY\":false,\"time\":4444},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerRecurringTime\"}"
private var timeJson = "{\"data\":{\"WEDNESDAY\":false,\"MONDAY\":false,\"THURSDAY\":false,\"SUNDAY\":false,\"TUESDAY\":false,\"FRIDAY\":false,\"SATURDAY\":false,\"time\":4444},\"type\":\"TriggerRecurringTime\"}"
@Test
fun toJSONTest() {

View file

@ -43,7 +43,7 @@ class TriggerTempTargetTest : TriggerTestBase() {
Assert.assertEquals(ComparatorExists.Compare.NOT_EXISTS, t1.comparator.value)
}
private var ttJson = "{\"data\":{\"comparator\":\"EXISTS\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTempTarget\"}"
private var ttJson = "{\"data\":{\"comparator\":\"EXISTS\"},\"type\":\"TriggerTempTarget\"}"
@Test fun toJSONTest() {
val t: TriggerTempTarget = TriggerTempTarget(injector).comparator(ComparatorExists.Compare.EXISTS)
Assert.assertEquals(ttJson, t.toJSON())

View file

@ -18,7 +18,7 @@ import org.powermock.modules.junit4.PowerMockRunner
class TriggerTimeRangeTest : TriggerTestBase() {
var now = 754 // in minutes from midnight
private var timeJson = "{\"data\":{\"start\":753,\"end\":784},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTimeRange\"}"
private var timeJson = "{\"data\":{\"start\":753,\"end\":784},\"type\":\"TriggerTimeRange\"}"
@Before
fun mock() {

View file

@ -36,7 +36,7 @@ class TriggerTimeTest : TriggerTestBase() {
Assert.assertFalse(t.shouldRun())
}
private var timeJson = "{\"data\":{\"runAt\":1514766840000},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime\"}"
private var timeJson = "{\"data\":{\"runAt\":1514766840000},\"type\":\"TriggerTime\"}"
@Test fun toJSONTest() {
val t: TriggerTime = TriggerTime(injector).runAt(now - T.mins(1).msecs())
Assert.assertEquals(timeJson, t.toJSON())

View file

@ -56,7 +56,7 @@ class TriggerWifiSsidTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
var json = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"ssid\":\"aSSID\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerWifiSsid\"}"
var json = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"ssid\":\"aSSID\"},\"type\":\"TriggerWifiSsid\"}"
@Test fun toJSONTest() {
val t: TriggerWifiSsid = TriggerWifiSsid(injector).setValue("aSSID").comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(json, t.toJSON())

View file

@ -67,6 +67,7 @@ fun ExtendedBolus.toRealJson(): JSONObject =
.put("splitExt", 100)
.put("enteredinsulin", amount)
.put("relative", rate)
.put("isValid", isValid)
.put("isEmulatingTempBasal", isEmulatingTempBasal)
.also {
if (interfaceIDs.pumpId != null) it.put("pumpId", interfaceIDs.pumpId)

View file

@ -16,10 +16,10 @@ abstract class PumpPluginBase(
override fun onStart() {
super.onStart()
if (getType() == PluginType.PUMP) {
Thread(Runnable {
Thread {
SystemClock.sleep(3000)
commandQueue.readStatus("Pump driver changed.", null)
}).start()
}.start()
}
}
}

View file

@ -23,6 +23,14 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
*/
interface PumpSync {
/**
* Reset stored identification of last used pump
*
* Call this function when new pump is paired to accept data from new pump
* to prevent overlapping pump histories
*/
fun connectNewPump()
/*
* GENERAL STATUS
*/

View file

@ -122,6 +122,7 @@ open class Notification {
const val OMNIPOD_STARTUP_STATUS_REFRESH_FAILED = 69
const val OMNIPOD_TIME_OUT_OF_SYNC = 70
const val UNSUPPORTED_ACTION_IN_PUMP = 71
const val WRONG_PUMP_DATA = 71
const val USER_MESSAGE = 1000

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.pump
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper
@ -14,8 +15,14 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject
@ -23,12 +30,54 @@ import javax.inject.Inject
class PumpSyncImplementation @Inject constructor(
private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val resourceHelper: ResourceHelper,
private val profileFunction: ProfileFunction,
private val repository: AppRepository
) : PumpSync {
private val disposable = CompositeDisposable()
override fun connectNewPump() {
sp.remove(R.string.key_active_pump_type)
sp.remove(R.string.key_active_pump_serial_number)
sp.remove(R.string.key_active_pump_change_timestamp)
}
/**
* Check if data is coming from currently active pump to prevent overlapping pump histories
*
* @param timestamp timestamp of data coming from pump
* @param type timestamp of of pump
* @param serialNumber serial number of of pump
* @return true if data is allowed
*/
private fun confirmActivePump(timestamp: Long, type: PumpType, serialNumber: String) : Boolean {
val storedType = sp.getString(R.string.key_active_pump_type, "")
val storedSerial = sp.getString(R.string.key_active_pump_serial_number, "")
val storedTimestamp = sp.getLong(R.string.key_active_pump_change_timestamp, 0L)
// If no value stored assume we start using new pump from now
if (storedType.isEmpty() || storedSerial.isEmpty()) {
aapsLogger.debug(LTag.PUMP, "Registering new pump ${type.description} $serialNumber")
sp.putString(R.string.key_active_pump_type, type.description)
sp.putString(R.string.key_active_pump_serial_number, serialNumber)
sp.putLong(R.string.key_active_pump_change_timestamp, dateUtil._now()) // allow only data newer than register time (ie. ignore older history)
return timestamp > dateUtil._now() - T.mins(1).msecs() // allow first record to be 1 min old
}
if (type.description == storedType && serialNumber == storedSerial && timestamp >= storedTimestamp) {
// data match
return true
}
if (type.description != storedType || serialNumber != storedSerial)
rxBus.send(EventNewNotification(Notification(Notification.WRONG_PUMP_DATA, resourceHelper.gs(R.string.wrong_pump_data), Notification.URGENT)))
aapsLogger.error(LTag.PUMP, "Ignoring pump history record $timestamp ${type.description} $serialNumber. Registered pump: $storedType $storedSerial")
return false
}
override fun expectedPumpState(): PumpSync.PumpState {
val bolus = repository.getLastBolusRecord()
val temporaryBasal = repository.getTemporaryBasalActiveAt(dateUtil._now()).blockingGet()
@ -68,6 +117,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun addBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
@ -88,6 +138,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncBolusWithTempId(timestamp: Long, amount: Double, temporaryId: Long, type: DetailedBolusInfo.BolusType?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
@ -109,6 +160,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncBolusWithPumpId(timestamp: Long, amount: Double, type: DetailedBolusInfo.BolusType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val bolus = Bolus(
timestamp = timestamp,
amount = amount,
@ -130,6 +182,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val carbs = Carbs(
timestamp = timestamp,
amount = amount,
@ -149,6 +202,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun insertTherapyEventIfNewWithTimestamp(timestamp: Long, type: DetailedBolusInfo.EventType, note: String?, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val therapyEvent = TherapyEvent(
timestamp = timestamp,
type = type.toDBbEventType(),
@ -175,6 +229,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun insertAnnouncement(error: String, pumpId: Long?, pumpType: PumpType, pumpSerial: String) {
if (!confirmActivePump(dateUtil._now(), pumpType, pumpSerial)) return
disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(error, pumpId, pumpType.toDbPumpType(), pumpSerial))
.subscribe()
}
@ -184,6 +239,7 @@ class PumpSyncImplementation @Inject constructor(
*/
override fun syncTemporaryBasalWithPumpId(timestamp: Long, rate: Double, duration: Long, isAbsolute: Boolean, type: PumpSync.TemporaryBasalType?, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val temporaryBasal = TemporaryBasal(
timestamp = timestamp,
rate = rate,
@ -207,6 +263,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncStopTemporaryBasalWithPumpId(timestamp: Long, endPumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
repository.runTransactionForResult(SyncPumpCancelTemporaryBasalIfAnyTransaction(timestamp, endPumpId, pumpType.toDbPumpType(), pumpSerial))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it) }
.blockingGet()
@ -231,6 +288,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncExtendedBolusWithPumpId(timestamp: Long, amount: Double, duration: Long, isEmulatingTB: Boolean, pumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val extendedBolus = ExtendedBolus(
timestamp = timestamp,
amount = amount,
@ -253,6 +311,7 @@ class PumpSyncImplementation @Inject constructor(
}
override fun syncStopExtendedBolusWithPumpId(timestamp: Long, endPumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
repository.runTransactionForResult(SyncPumpCancelExtendedBolusIfAnyTransaction(timestamp, endPumpId, pumpType.toDbPumpType(), pumpSerial))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it) }
.blockingGet()

View file

@ -33,6 +33,7 @@ object SealedClassHelper {
val x = gson.fromJson<T>(jsonReader, innerClass.javaObjectType)
jsonReader.endObject()
// if there a static object, actually return that
@Suppress("UNCHECKED_CAST")
return innerClass.objectInstance as T? ?: x
}

View file

@ -55,6 +55,9 @@
<string name="key_insight_local_settings" translatable="false">insight_local_settings</string>
<string name="key_data_choices_settings" translatable="false">data_choices_settings</string>
<string name="key_dexcom_settings" translatable="false">dexcom_settings</string>
<string name="key_active_pump_change_timestamp" translatable="false">active_pump_change_timestamp</string>
<string name="key_active_pump_type" translatable="false">active_pump_type</string>
<string name="key_active_pump_serial_number" translatable="false">active_pump_serial_number</string>
<!-- General-->
<string name="refresh">Refresh</string>
@ -160,6 +163,7 @@
<string name="notes_label">Notes</string>
<string name="remove_button">Remove</string>
<string name="addnew">Add new</string>
<string name="wrong_pump_data">Data is coming from different pump. Change pump driver to reset pump state.</string>
<!-- Constraints-->
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string>

View file

@ -29,6 +29,7 @@ class MsgInitConnStatusTime_k(
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
danaRPlugin.setFragmentVisible(PluginType.PUMP, true)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingKoreanDanaDriver")
rxBus.send(EventRebuildTabs())

View file

@ -344,6 +344,58 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
return result;
}
@NonNull @Override
public PumpEnactResult setExtendedBolus(double insulin, int durationInMinutes) {
DanaPump pump = danaPump;
insulin = constraintChecker.applyExtendedBolusConstraints(new Constraint<>(insulin)).value();
// needs to be rounded
int durationInHalfHours = Math.max(durationInMinutes / 30, 1);
insulin = Round.roundTo(insulin, getPumpDescription().getExtendedBolusStep());
PumpEnactResult result = new PumpEnactResult(getInjector());
if (danaPump.isExtendedInProgress() && Math.abs(danaPump.getExtendedBolusAmount() - insulin) < pumpDescription.getExtendedBolusStep()) {
result.enacted(false)
.success(true)
.comment(R.string.ok)
.duration(pump.getExtendedBolusRemainingMinutes())
.absolute(pump.getExtendedBolusAbsoluteRate())
.isPercent(false)
.isTempCancel(false);
getAapsLogger().debug(LTag.PUMP, "setExtendedBolus: Correct extended bolus already set. Current: " + pump.getExtendedBolusAmount() + " Asked: " + insulin);
return result;
}
boolean connectionOK = sExecutionService.extendedBolus(insulin, durationInHalfHours);
if (connectionOK && pump.isExtendedInProgress() && Math.abs(pump.getExtendedBolusAmount() - insulin) < getPumpDescription().getExtendedBolusStep()) {
result.enacted(true)
.success(true)
.comment(R.string.ok)
.isTempCancel(false)
.duration(pump.getExtendedBolusRemainingMinutes())
.absolute(pump.getExtendedBolusAbsoluteRate())
.isPercent(false);
if (!sp.getBoolean("danar_useextended", false))
result.bolusDelivered(pump.getExtendedBolusAmount());
getAapsLogger().debug(LTag.PUMP, "setExtendedBolus: OK");
return result;
}
result.enacted(false).success(false).comment(R.string.danar_valuenotsetproperly);
getAapsLogger().error("setExtendedBolus: Failed to extended bolus");
return result;
}
@NonNull @Override
public PumpEnactResult cancelExtendedBolus() {
PumpEnactResult result = new PumpEnactResult(getInjector());
if (danaPump.isExtendedInProgress()) {
sExecutionService.extendedBolusStop();
result.enacted(true).success(!danaPump.isExtendedInProgress()).isTempCancel(true);
} else {
result.success(true).enacted(false).comment(R.string.ok);
getAapsLogger().debug(LTag.PUMP, "cancelExtendedBolus: OK");
}
return result;
}
@NonNull @Override
public PumpType model() {
return PumpType.DANA_RV2;

View file

@ -27,7 +27,6 @@ class MsgCheckValue_v2(
danaPump.protocol = intFromBuff(bytes, 1, 1)
danaPump.productCode = intFromBuff(bytes, 2, 1)
if (danaPump.hwModel != DanaPump.EXPORT_MODEL) {
danaPump.reset()
val notification = Notification(Notification.WRONG_DRIVER, resourceHelper.gs(R.string.pumpdrivercorrected), Notification.NORMAL)
rxBus.send(EventNewNotification(notification))
danaRPlugin.disconnect("Wrong Model")
@ -37,6 +36,7 @@ class MsgCheckValue_v2(
danaRPlugin.setPluginEnabled(PluginType.PUMP, false)
danaRPlugin.setFragmentVisible(PluginType.PUMP, false)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingDanaRv2Driver")
rxBus.send(EventRebuildTabs())
@ -44,7 +44,6 @@ class MsgCheckValue_v2(
return
}
if (danaPump.protocol != 2) {
danaPump.reset()
val notification = Notification(Notification.WRONG_DRIVER, resourceHelper.gs(R.string.pumpdrivercorrected), Notification.NORMAL)
rxBus.send(EventNewNotification(notification))
danaRKoreanPlugin.disconnect("Wrong Model")
@ -53,6 +52,8 @@ class MsgCheckValue_v2(
danaRv2Plugin.setFragmentVisible(PluginType.PUMP, false)
danaRPlugin.setPluginEnabled(PluginType.PUMP, true)
danaRPlugin.setFragmentVisible(PluginType.PUMP, true)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingDanaRv2Driver")
rxBus.send(EventRebuildTabs())

View file

@ -112,6 +112,7 @@ public abstract class AbstractDanaRPlugin extends PumpPluginBase implements Pump
.subscribe(event -> {
if (event.isChanged(getResourceHelper(), R.string.key_danar_bt_name)) {
danaPump.reset();
pumpSync.connectNewPump();
getCommandQueue().readStatus("DeviceChanged", null);
}
})

View file

@ -25,7 +25,7 @@ class MsgInitConnStatusBasic(
danaPump.currentBasal = intFromBuff(bytes, 11, 2) / 100.0
val tempBasalPercent = intFromBuff(bytes, 13, 1)
val isExtendedInProgress = intFromBuff(bytes, 14, 1) == 1
val isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1
//val isTempBasalInProgress = intFromBuff(bytes, 15, 1) == 1
val statusBasalUDOption = intFromBuff(bytes, 16, 1)
danaPump.isDualBolusInProgress = intFromBuff(bytes, 17, 1) == 1
val extendedBolusRate = intFromBuff(bytes, 18, 2) / 100.0
@ -46,8 +46,8 @@ class MsgInitConnStatusBasic(
aapsLogger.debug(LTag.PUMPCOMM, "Reservoir remaining units: " + danaPump.reservoirRemainingUnits)
aapsLogger.debug(LTag.PUMPCOMM, "Bolus blocked: " + danaPump.bolusBlocked)
aapsLogger.debug(LTag.PUMPCOMM, "Current basal: " + danaPump.currentBasal)
aapsLogger.debug(LTag.PUMPCOMM, "Current temp basal percent: " + tempBasalPercent)
aapsLogger.debug(LTag.PUMPCOMM, "Is extended bolus running: " + isExtendedInProgress)
aapsLogger.debug(LTag.PUMPCOMM, "Current temp basal percent: $tempBasalPercent")
aapsLogger.debug(LTag.PUMPCOMM, "Is extended bolus running: $isExtendedInProgress")
aapsLogger.debug(LTag.PUMPCOMM, "statusBasalUDOption: $statusBasalUDOption")
aapsLogger.debug(LTag.PUMPCOMM, "Is dual bolus running: " + danaPump.isDualBolusInProgress)
aapsLogger.debug(LTag.PUMPCOMM, "Extended bolus rate: $extendedBolusRate")

View file

@ -28,6 +28,7 @@ class MsgInitConnStatusTime(
danaRPlugin.setPluginEnabled(PluginType.PUMP, false)
danaRPlugin.setFragmentVisible(PluginType.PUMP, false)
danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingDanaDriver")
rxBus.send(EventRebuildTabs())

View file

@ -16,8 +16,10 @@ class MsgStatusTempBasal(
aapsLogger.debug(LTag.PUMPCOMM, "New message")
}
var isTempBasalInProgress = false
override fun handleMessage(bytes: ByteArray) {
val isTempBasalInProgress = intFromBuff(bytes, 0, 1) and 0x01 == 0x01
isTempBasalInProgress = intFromBuff(bytes, 0, 1) and 0x01 == 0x01
val isAPSTempBasalInProgress = intFromBuff(bytes, 0, 1) and 0x02 == 0x02
var tempBasalPercent = intFromBuff(bytes, 1, 1)
if (tempBasalPercent > 200) tempBasalPercent = (tempBasalPercent - 200) * 10
@ -47,7 +49,7 @@ class MsgStatusTempBasal(
}
private fun getDateFromSecAgo(tempBasalAgoSecs: Int): Long {
return (floor(System.currentTimeMillis() / 1000.0) - tempBasalAgoSecs).toLong() * 1000
return (floor(dateUtil._now() / 1000.0) - tempBasalAgoSecs).toLong() * 1000
}
// because there is no fixed timestamp of start allow update of tbr only if tbr start differs more

View file

@ -32,7 +32,6 @@ open class DanaRTestBase : TestBase() {
@Mock lateinit var activePluginProvider: ActivePluginProvider
@Mock lateinit var dateUtil: DateUtil
@Mock lateinit var databaseHelper: DatabaseHelperInterface
@Mock lateinit var treatmentsInterface: TreatmentsInterface
@Mock lateinit var danaRPlugin: DanaRPlugin
@Mock lateinit var danaRKoreanPlugin: DanaRKoreanPlugin
@Mock lateinit var danaRv2Plugin: DanaRv2Plugin
@ -49,7 +48,6 @@ open class DanaRTestBase : TestBase() {
fun setup() {
danaPump = DanaPump(aapsLogger, sp, dateUtil, injector)
testPumpPlugin = TestPumpPlugin(injector)
`when`(activePluginProvider.activeTreatments).thenReturn(treatmentsInterface)
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
doNothing().`when`(danaRKoreanPlugin).setPluginEnabled(anyObject(), anyBoolean())
doNothing().`when`(danaRPlugin).setPluginEnabled(anyObject(), anyBoolean())

View file

@ -5,7 +5,6 @@ import info.nightscout.androidaps.utils.T
import org.junit.Assert
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
@ -13,12 +12,12 @@ class MsgStatusBolusExtendedTest : DanaRTestBase() {
@Test
fun runTest() {
`when`(activePluginProvider.activeTreatments).thenReturn(treatmentsInterface)
val packet = MsgStatusBolusExtended(injector)
// test message decoding
val array = ByteArray(100)
putByteToArray(array, 0, 1)
putByteToArray(array, 1, 1)
packet.handleMessage(array)
Assert.assertEquals(T.mins(30).msecs() , danaPump.extendedBolusDuration)
Assert.assertEquals(T.mins(30).msecs(), danaPump.extendedBolusDuration)
}
}

View file

@ -12,11 +12,10 @@ class MsgStatusTempBasalTest : DanaRTestBase() {
@Test fun runTest() {
val packet = MsgStatusTempBasal(injector)
// test message decoding
// test message decoding
packet.handleMessage(createArray(34, 1.toByte()))
Assert.assertEquals(true, danaPump.isTempBasalInProgress)
Assert.assertEquals(true, packet.isTempBasalInProgress)
// passing an bigger number
packet.handleMessage(createArray(34, 2.toByte()))
Assert.assertEquals(false, danaPump.isTempBasalInProgress)
Assert.assertEquals(false, packet.isTempBasalInProgress)
}
}

View file

@ -48,7 +48,7 @@ class DanaRKoreanPluginTest : TestBaseWithProfile() {
`when`(resourceHelper.gs(R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
`when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
danaPump = DanaPump(aapsLogger, sp, dateUtil, injector)
danaRPlugin = DanaRKoreanPlugin(injector, aapsLogger, aapsSchedulers, rxBus, danaPump, context, resourceHelper, constraintChecker, activePluginProvider, sp, commandQueue, dateUtil, pumpSync, fabricPrivacy)
danaRPlugin = DanaRKoreanPlugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, activePluginProvider, sp, commandQueue, danaPump, dateUtil, fabricPrivacy, pumpSync)
}
@Test @Throws(Exception::class)

View file

@ -25,7 +25,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class)
@PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class)
class DanaRv2PluginTest : TestBaseWithProfile() {
@Mock lateinit var context: Context
@ -51,7 +51,7 @@ class DanaRv2PluginTest : TestBaseWithProfile() {
`when`(resourceHelper.gs(R.string.limitingbasalratio)).thenReturn("Limiting max basal rate to %1\$.2f U/h because of %2\$s")
`when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
danaPump = DanaPump(aapsLogger, sp, dateUtil, injector)
danaRv2Plugin = DanaRv2Plugin(injector, aapsLogger, aapsSchedulers, rxBus, context, danaPump, resourceHelper, constraintChecker, activePluginProvider, sp, commandQueue, detailedBolusInfoStorage, temporaryBasalStorage, dateUtil, fabricPrivacy, pumpSync)
danaRv2Plugin = DanaRv2Plugin(injector, aapsLogger, aapsSchedulers, rxBus, context, resourceHelper, constraintChecker, activePluginProvider, sp, commandQueue, danaPump,detailedBolusInfoStorage, temporaryBasalStorage, dateUtil, fabricPrivacy, pumpSync)
}
@Test

View file

@ -19,12 +19,12 @@ class MsgHistoryEventsRv2Test : DanaRTestBase() {
// test message decoding
val array = createArray(100, 2)
putByteToArray(array, 0, 0xFF.toByte())
packet.handleMessage(array)
Assert.assertEquals(true, danaPump.historyDoneReceived)
// passing an bigger number
putByteToArray(array, 0, 0x01.toByte())
packet.handleMessage(array)
Assert.assertEquals(false, danaPump.historyDoneReceived)
putByteToArray(array, 0, 0xFF.toByte())
packet.handleMessage(array)
Assert.assertEquals(true, danaPump.historyDoneReceived)
}
}

View file

@ -134,6 +134,7 @@ class DanaRSPlugin @Inject constructor(
mDeviceAddress = sp.getString(R.string.key_danars_address, "")
mDeviceName = sp.getString(R.string.key_danars_name, "")
danaPump.reset()
pumpSync.connectNewPump()
commandQueue.readStatus("DeviceChanged", null)
}

View file

@ -19,14 +19,18 @@ class DanaRS_Packet_Basal_Get_Temporary_Basal_State(
aapsLogger.debug(LTag.PUMPCOMM, "Requesting temporary basal status")
}
var isTempBasalInProgress: Boolean = false
var tempBasalTotalSec: Int = 0
var tempBasalPercent: Int = 0
override fun handleMessage(data: ByteArray) {
val error = byteArrayToInt(getBytes(data, DATA_START, 1))
val isTempBasalInProgress = byteArrayToInt(getBytes(data, DATA_START + 1, 1)) == 0x01
isTempBasalInProgress = byteArrayToInt(getBytes(data, DATA_START + 1, 1)) == 0x01
val isAPSTempBasalInProgress = byteArrayToInt(getBytes(data, DATA_START + 1, 1)) == 0x02
var tempBasalPercent = byteArrayToInt(getBytes(data, DATA_START + 2, 1))
tempBasalPercent = byteArrayToInt(getBytes(data, DATA_START + 2, 1))
if (tempBasalPercent > 200) tempBasalPercent = (tempBasalPercent - 200) * 10
val durationHour = byteArrayToInt(getBytes(data, DATA_START + 3, 1))
val tempBasalTotalSec: Int = if (durationHour == 150) 15 * 60 else if (durationHour == 160) 30 * 60 else durationHour * 60 * 60
tempBasalTotalSec = if (durationHour == 150) 15 * 60 else if (durationHour == 160) 30 * 60 else durationHour * 60 * 60
val runningMin = byteArrayToInt(getBytes(data, DATA_START + 4, 2))
if (error != 0) failed = true
val tempBasalRemainingMin = (danaPump.tempBasalTotalSec - runningMin * 60) / 60

View file

@ -18,13 +18,15 @@ class DanaRS_Packet_Bolus_Get_Extended_Bolus_State(
aapsLogger.debug(LTag.PUMPCOMM, "New message")
}
var isExtendedInProgress: Boolean = false
override fun handleMessage(data: ByteArray) {
var dataIndex = DATA_START
var dataSize = 1
val error = byteArrayToInt(getBytes(data, dataIndex, dataSize))
dataIndex += dataSize
dataSize = 1
val isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01
isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01
dataIndex += dataSize
dataSize = 1
val extendedBolusDuration = T.mins(byteArrayToInt(getBytes(data, dataIndex, dataSize)) * 30L).msecs()

View file

@ -17,13 +17,15 @@ class DanaRS_Packet_Bolus_Get_Extended_Menu_Option_State(
aapsLogger.debug(LTag.PUMPCOMM, "New message")
}
var isExtendedInProgress: Boolean = false
override fun handleMessage(data: ByteArray) {
var dataIndex = DATA_START
var dataSize = 1
val extendedMenuOption = byteArrayToInt(getBytes(data, dataIndex, dataSize))
dataIndex += dataSize
dataSize = 1
val isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01
isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01
aapsLogger.debug(LTag.PUMPCOMM, "extendedMenuOption: $extendedMenuOption")
}

View file

@ -23,7 +23,7 @@ import org.powermock.modules.junit4.PowerMockRunner
@Suppress("SpellCheckingInspection")
@RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, RxBusWrapper::class, DetailedBolusInfoStorage::class)
@PrepareForTest(ConstraintChecker::class, RxBusWrapper::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class)
class DanaRSPluginTest : DanaRSTestBase() {
@Mock lateinit var context: Context

View file

@ -5,7 +5,6 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.dana.DanaPump
import info.nightscout.androidaps.danars.comm.DanaRS_Packet
import info.nightscout.androidaps.db.TemporaryBasal
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Before
import org.mockito.ArgumentMatchers
@ -16,16 +15,7 @@ open class DanaRSTestBase : TestBaseWithProfile() {
@Mock lateinit var sp: SP
val injector = HasAndroidInjector {
AndroidInjector {
if (it is TemporaryBasal) {
it.aapsLogger = aapsLogger
it.activePlugin = activePluginProvider
it.profileFunction = profileFunction
it.sp = sp
}
}
}
val injector = HasAndroidInjector { AndroidInjector { } }
lateinit var danaPump: DanaPump

View file

@ -20,7 +20,7 @@ import org.powermock.modules.junit4.PowerMockRunner
import java.util.*
@RunWith(PowerMockRunner::class)
@PrepareForTest(RxBusWrapper::class, DetailedBolusInfoStorage::class, DanaRSPlugin::class)
@PrepareForTest(RxBusWrapper::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class, DanaRSPlugin::class)
class DanaRsPacketApsHistoryEventsTest : DanaRSTestBase() {
@Mock lateinit var context: Context

View file

@ -34,9 +34,9 @@ class DanaRsPacketBasalGetTemporaryBasalStateTest : DanaRSTestBase() {
putIntToArray(array, 4, 1)
packet.handleMessage(array)
Assert.assertTrue(packet.failed)
Assert.assertTrue(danaPump.isTempBasalInProgress)
Assert.assertEquals(300, danaPump.tempBasalPercent)
Assert.assertEquals(15 * 60, danaPump.tempBasalTotalSec)
Assert.assertTrue(packet.isTempBasalInProgress)
Assert.assertEquals(300, packet.tempBasalPercent)
Assert.assertEquals(15 * 60, packet.tempBasalTotalSec)
Assert.assertEquals("BASAL__TEMPORARY_BASAL_STATE", packet.friendlyName)
}
}

View file

@ -33,7 +33,6 @@ class DanaRsPacketBolusGetDualBolusTest : DanaRSTestBase() {
packet.handleMessage(array)
Assert.assertTrue(packet.failed)
Assert.assertEquals(1.0, danaPump.bolusStep, 0.0)
Assert.assertEquals(0.55, danaPump.extendedBolusAbsoluteRate, 0.0)
Assert.assertEquals(40.0, danaPump.maxBolus, 0.0)
Assert.assertEquals("BOLUS__GET_DUAL_BOLUS", packet.friendlyName)

View file

@ -31,7 +31,7 @@ class DanaRsPacketBolusGetExtendedBolusStateTest : DanaRSTestBase() {
testValue = 1.0
packet.handleMessage(createArray(11, testValue.toInt().toByte()))
// is extended bolus in progress
Assert.assertEquals(testValue == 1.0, danaPump.isExtendedInProgress)
Assert.assertEquals(testValue == 1.0, packet.isExtendedInProgress)
Assert.assertEquals(testValue != 0.0, packet.failed)
Assert.assertEquals("BOLUS__GET_EXTENDED_BOLUS_STATE", packet.friendlyName)
}

View file

@ -26,10 +26,10 @@ class DanaRsPacketBolusGetExtendedMenuOptionStateTest : DanaRSTestBase() {
// test message decoding
packet.handleMessage(createArray(34, 0.toByte()))
// isExtendedInProgress should be false
Assert.assertEquals(false, danaPump.isExtendedInProgress)
Assert.assertEquals(false, packet.isExtendedInProgress)
// assertEquals(false, packet.failed);
packet.handleMessage(createArray(34, 1.toByte()))
Assert.assertEquals(true, danaPump.isExtendedInProgress)
Assert.assertEquals(true, packet.isExtendedInProgress)
Assert.assertEquals("BOLUS__GET_EXTENDED_MENU_OPTION_STATE", packet.friendlyName)
}
}

View file

@ -21,7 +21,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class)
@PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class)
class DanaRsPacketBolusSetStepBolusStartTest : DanaRSTestBase() {
@Mock lateinit var constraintChecker: ConstraintChecker

View file

@ -44,8 +44,6 @@ class DanaRsPacketGeneralGetMoreInformationTest : DanaRSTestBase() {
Assert.assertFalse(packet.failed)
Assert.assertEquals(6.0, danaPump.iob, 0.01)
Assert.assertEquals(12.5, danaPump.dailyTotalUnits, 0.01)
Assert.assertTrue(danaPump.isExtendedInProgress)
Assert.assertEquals(150, danaPump.extendedBolusRemainingMinutes)
val lastBolus = Calendar.getInstance()
lastBolus.timeInMillis = danaPump.lastBolusTime
Assert.assertEquals(15, lastBolus.get(Calendar.HOUR_OF_DAY))

View file

@ -24,7 +24,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, RxBusWrapper::class, DetailedBolusInfoStorage::class)
@PrepareForTest(ConstraintChecker::class, RxBusWrapper::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class)
class DanaRsPacketNotifyDeliveryRateDisplayTest : DanaRSTestBase() {
@Mock lateinit var activePlugin: ActivePluginProvider

View file

@ -33,6 +33,7 @@ object SealedClassHelper {
val x = gson.fromJson<T>(jsonReader, innerClass.javaObjectType)
jsonReader.endObject()
// if there a static object, actually return that
@Suppress("UNCHECKED_CAST")
return innerClass.objectInstance as T? ?: x
}

View file

@ -68,9 +68,10 @@ public class OmnipodErosPumpPluginTest {
OmnipodErosPumpPlugin plugin = new OmnipodErosPumpPlugin(injector, aapsLogger, new TestAapsSchedulers(), rxBusWrapper, null,
resourceHelper, activePluginProvider, null, null, aapsOmnipodErosManager, commandQueueProvider,
null, null, null, null,
rileyLinkUtil, null, null, null
rileyLinkUtil, null, null, pumpSync
);
when(pumpSync.expectedPumpState().getTemporaryBasal()).thenReturn(null);
PumpSync.PumpState pumpState = new PumpSync.PumpState(null, null, null, null);
when(pumpSync.expectedPumpState()).thenReturn(pumpState);
when(rileyLinkUtil.getRileyLinkHistory()).thenReturn(new ArrayList<>());
when(injector.androidInjector()).thenReturn(instance -> {
});