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 bindCommandQueueProvider(commandQueue: CommandQueue): CommandQueueProvider
@Binds fun bindConfigInterface(config: Config): ConfigInterface @Binds fun bindConfigInterface(config: Config): ConfigInterface
@Binds fun bindConfigBuilderInterface(configBuilderPlugin: ConfigBuilderPlugin): ConfigBuilderInterface @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 bindDatabaseHelperInterface(databaseHelperProvider: DatabaseHelperProvider): DatabaseHelperInterface
@Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolder): NotificationHolderInterface @Binds fun bindNotificationHolderInterface(notificationHolder: NotificationHolder): NotificationHolderInterface
@Binds fun bindImportExportPrefsInterface(importExportPrefs: ImportExportPrefs): ImportExportPrefsInterface @Binds fun bindImportExportPrefsInterface(importExportPrefs: ImportExportPrefs): ImportExportPrefsInterface

View file

@ -30,7 +30,8 @@ class ConfigBuilderPlugin @Inject constructor(
private val sp: SP, private val sp: SP,
private val rxBus: RxBusWrapper, private val rxBus: RxBusWrapper,
private val activePlugin: ActivePluginProvider, private val activePlugin: ActivePluginProvider,
private val uel: UserEntryLogger private val uel: UserEntryLogger,
private val pumpSync: PumpSync
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.fragmentClass(ConfigBuilderFragment::class.java.name) .fragmentClass(ConfigBuilderFragment::class.java.name)
@ -141,14 +142,16 @@ class ConfigBuilderPlugin @Inject constructor(
val allowHardwarePump = sp.getBoolean("allow_hardware_pump", false) val allowHardwarePump = sp.getBoolean("allow_hardware_pump", false)
if (allowHardwarePump || activity == null) { if (allowHardwarePump || activity == null) {
performPluginSwitch(changedPlugin, newState, type) performPluginSwitch(changedPlugin, newState, type)
pumpSync.connectNewPump()
} else { } 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) performPluginSwitch(changedPlugin, newState, type)
pumpSync.connectNewPump()
sp.putBoolean("allow_hardware_pump", true) sp.putBoolean("allow_hardware_pump", true)
uel.log(Action.HW_PUMP_ALLOWED, Sources.ConfigBuilder, uel.log(Action.HW_PUMP_ALLOWED, Sources.ConfigBuilder,
ValueWithUnit.StringResource(changedPlugin.pluginDescription.pluginName)) ValueWithUnit.StringResource(changedPlugin.pluginDescription.pluginName))
aapsLogger.debug(LTag.PUMP, "First time HW pump allowed!") aapsLogger.debug(LTag.PUMP, "First time HW pump allowed!")
}, Runnable { }, {
rxBus.send(EventConfigBuilderUpdateGui()) rxBus.send(EventConfigBuilderUpdateGui())
aapsLogger.debug(LTag.PUMP, "User does not allow switching to HW pump!") 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.DataSyncSelector
import info.nightscout.androidaps.interfaces.DatabaseHelperInterface import info.nightscout.androidaps.interfaces.DatabaseHelperInterface
import info.nightscout.androidaps.interfaces.ImportExportPrefsInterface import info.nightscout.androidaps.interfaces.ImportExportPrefsInterface
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
@ -39,6 +40,7 @@ class MaintenanceFragment : DaggerFragment() {
@Inject lateinit var databaseHelper: DatabaseHelperInterface @Inject lateinit var databaseHelper: DatabaseHelperInterface
@Inject lateinit var uel: UserEntryLogger @Inject lateinit var uel: UserEntryLogger
@Inject lateinit var dataSyncSelector: DataSyncSelector @Inject lateinit var dataSyncSelector: DataSyncSelector
@Inject lateinit var pumpSync: PumpSync
private val compositeDisposable = CompositeDisposable() private val compositeDisposable = CompositeDisposable()
@ -68,6 +70,7 @@ class MaintenanceFragment : DaggerFragment() {
databaseHelper.resetDatabases() databaseHelper.resetDatabases()
repository.clearDatabases() repository.clearDatabases()
dataSyncSelector.resetToNextFullSync() dataSyncSelector.resetToNextFullSync()
pumpSync.connectNewPump()
} }
.subscribeOn(aapsSchedulers.io) .subscribeOn(aapsSchedulers.io)
.observeOn(aapsSchedulers.main) .observeOn(aapsSchedulers.main)

View file

@ -53,7 +53,7 @@ import java.util.*
@PrepareForTest( @PrepareForTest(
ConfigBuilderPlugin::class, ConstraintChecker::class, SP::class, Context::class, ConfigBuilderPlugin::class, ConstraintChecker::class, SP::class, Context::class,
OpenAPSAMAPlugin::class, OpenAPSSMBPlugin::class, TreatmentsPlugin::class, TreatmentService::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) UserEntryLogger::class, IobCobCalculatorPlugin::class, LoggerUtils::class, AppRepository::class)
class ConstraintsCheckerTest : TestBaseWithProfile() { class ConstraintsCheckerTest : TestBaseWithProfile() {

View file

@ -1,15 +1,12 @@
package info.nightscout.androidaps.plugins.configBuilder package info.nightscout.androidaps.plugins.configBuilder
import dagger.Lazy
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.interfaces.ActivePluginProvider 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.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper 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.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Before import org.junit.Before
@ -23,22 +20,15 @@ import org.powermock.modules.junit4.PowerMockRunner
@PrepareForTest(UserEntryLogger::class) @PrepareForTest(UserEntryLogger::class)
class ConfigBuilderPluginTest : TestBase() { class ConfigBuilderPluginTest : TestBase() {
@Mock lateinit var virtualPumpPlugin: Lazy<VirtualPumpPlugin>
@Mock lateinit var treatmentsPlugin: Lazy<TreatmentsPlugin>
@Mock lateinit var sp: SP @Mock lateinit var sp: SP
@Mock lateinit var resourceHelper: ResourceHelper @Mock lateinit var resourceHelper: ResourceHelper
@Mock lateinit var commandQueue: CommandQueueProvider
@Mock lateinit var activePlugin: ActivePluginProvider @Mock lateinit var activePlugin: ActivePluginProvider
@Mock lateinit var uel: UserEntryLogger @Mock lateinit var uel: UserEntryLogger
@Mock lateinit var pumpSync: PumpSync
private lateinit var configBuilderPlugin: ConfigBuilderPlugin private lateinit var configBuilderPlugin: ConfigBuilderPlugin
val injector = HasAndroidInjector { val injector = HasAndroidInjector { AndroidInjector { } }
AndroidInjector {
}
}
@Test @Test
fun dummy() { fun dummy() {
@ -47,6 +37,6 @@ class ConfigBuilderPluginTest : TestBase() {
@Before @Before
fun prepareMock() { 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 null
}.`when`(commandQueue).bolus(anyObject(), ArgumentMatchers.any(Callback::class.java)) }.`when`(commandQueue).bolus(anyObject(), ArgumentMatchers.any(Callback::class.java))
Mockito.doAnswer { invocation: InvocationOnMock -> 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.result = PumpEnactResult(injector).success(true).isPercent(true).percent(invocation.getArgument(0)).duration(invocation.getArgument(1))
callback.run() callback.run()
null 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 -> 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.result = PumpEnactResult(injector).success(true).isPercent(false).absolute(invocation.getArgument(0)).duration(invocation.getArgument(1))
callback.run() callback.run()
null 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 -> Mockito.doAnswer { invocation: InvocationOnMock ->
val callback = invocation.getArgument<Callback>(2) val callback = invocation.getArgument<Callback>(2)
callback.result = PumpEnactResult(injector).success(true).isPercent(false).absolute(invocation.getArgument(0)).duration(invocation.getArgument(1)) 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 @Test
fun createBucketedData5minTest() { fun createBucketedData5minTest1() {
val bgReadingList: MutableList<GlucoseValue> = ArrayList() val bgReadingList: MutableList<GlucoseValue> = ArrayList()
// Super data should not be touched // 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(90.0, iobCobCalculatorPlugin.bucketedData!![1].value, 1.0)
Assert.assertEquals(50.0, iobCobCalculatorPlugin.bucketedData!![5].value, 1.0) Assert.assertEquals(50.0, iobCobCalculatorPlugin.bucketedData!![5].value, 1.0)
Assert.assertEquals(40.0, iobCobCalculatorPlugin.bucketedData!![6].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 //bucketed data should be null if no bg data available
iobCobCalculatorPlugin.bgReadings = ArrayList() iobCobCalculatorPlugin.bgReadings = ArrayList()

View file

@ -48,6 +48,8 @@ class TreatmentsPluginTest : TestBaseWithProfile() {
} }
} }
} }
@Test fun dumy() {}
/* /*
private lateinit var insulinOrefRapidActingPlugin: InsulinOrefRapidActingPlugin private lateinit var insulinOrefRapidActingPlugin: InsulinOrefRapidActingPlugin
private lateinit var sot: TreatmentsPlugin 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.ActivePluginProvider
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.TreatmentsInterface
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.dialogs.ChooseTriggerDialog 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.DateUtil
import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
import javax.inject.Inject import javax.inject.Inject
import kotlin.reflect.full.primaryConstructor
abstract class Trigger(val injector: HasAndroidInjector) { abstract class Trigger(val injector: HasAndroidInjector) {
@ -50,7 +47,7 @@ abstract class Trigger(val injector: HasAndroidInjector) {
} }
abstract fun shouldRun(): Boolean abstract fun shouldRun(): Boolean
abstract fun toJSON(): String abstract fun dataJSON(): JSONObject
abstract fun fromJSON(data: String): Trigger abstract fun fromJSON(data: String): Trigger
abstract fun friendlyName(): Int abstract fun friendlyName(): Int
@ -77,23 +74,56 @@ abstract class Trigger(val injector: HasAndroidInjector) {
root.addView(title) root.addView(title)
} }
fun toJSON(): String =
JSONObject()
.put("type", this::class.java.simpleName)
.put("data", dataJSON())
.toString()
fun instantiate(obj: JSONObject): Trigger? { fun instantiate(obj: JSONObject): Trigger? {
try {
val type = obj.getString("type") val type = obj.getString("type")
val data = obj.getJSONObject("data") val data = obj.getJSONObject("data")
val clazz = Class.forName(type).kotlin //val clazz = Class.forName(type).kotlin
return (clazz.primaryConstructor?.call(injector) as Trigger).fromJSON(data?.toString() //return (clazz.primaryConstructor?.call(injector) as Trigger).fromJSON(data?.toString() ?: "")
?: "") return when (type) {
} catch (e: ClassNotFoundException) { TriggerAutosensValue::class.java.name, // backward compatibility
aapsLogger.error("Unhandled exception", e) TriggerAutosensValue::class.java.simpleName -> TriggerAutosensValue(injector).fromJSON(data?.toString() ?: "")
} catch (e: InstantiationException) { TriggerBg::class.java.name,
aapsLogger.error("Unhandled exception", e) TriggerBg::class.java.simpleName -> TriggerBg(injector).fromJSON(data?.toString() ?: "")
} catch (e: IllegalAccessException) { TriggerBolusAgo::class.java.name,
aapsLogger.error("Unhandled exception", e) TriggerBolusAgo::class.java.simpleName -> TriggerBolusAgo(injector).fromJSON(data?.toString() ?: "")
} catch (e: JSONException) { TriggerBTDevice::class.java.name,
aapsLogger.error("Unhandled exception", e) 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 { fun createAddButton(context: Context, trigger: TriggerConnector): ImageButton {

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,6 +19,7 @@ import org.json.JSONObject
import java.util.* import java.util.*
class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) { class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
var list: MutableList<Trigger> = ArrayList() var list: MutableList<Trigger> = ArrayList()
private var connectorType: Type = Type.AND private var connectorType: Type = Type.AND
@ -40,6 +41,7 @@ class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
} }
companion object { companion object {
fun labels(resourceHelper: ResourceHelper): List<String> { fun labels(resourceHelper: ResourceHelper): List<String> {
val list: MutableList<String> = ArrayList() val list: MutableList<String> = ArrayList()
for (t in values()) { for (t in values()) {
@ -79,16 +81,12 @@ class TriggerConnector(injector: HasAndroidInjector) : Trigger(injector) {
return result return result
} }
@Synchronized override fun toJSON(): String { override fun dataJSON(): JSONObject {
val array = JSONArray() val array = JSONArray()
for (t in list) array.put(t.toJSON()) for (t in list) array.put(t.toJSON())
val data = JSONObject() return JSONObject()
.put("connectorType", connectorType.toString()) .put("connectorType", connectorType.toString())
.put("triggerList", array) .put("triggerList", array)
return JSONObject()
.put("type", TriggerConnector::class.java.name)
.put("data", data)
.toString()
} }
override fun fromJSON(data: String): Trigger { 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.LabelWithElement
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
import info.nightscout.androidaps.utils.JsonHelper import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject import org.json.JSONObject
import java.text.DecimalFormat import java.text.DecimalFormat
@ -25,6 +24,7 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
var comparator: Comparator = Comparator(resourceHelper) var comparator: Comparator = Comparator(resourceHelper)
companion object { companion object {
private const val MMOL_MAX = 4.0 private const val MMOL_MAX = 4.0
private const val MGDL_MAX = 72.0 private const val MGDL_MAX = 72.0
} }
@ -85,17 +85,12 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
return false return false
} }
override fun toJSON(): String { override fun dataJSON(): JSONObject =
val data = JSONObject() JSONObject()
.put("value", delta.value) .put("value", delta.value)
.put("units", units) .put("units", units)
.put("deltaType", delta.deltaType) .put("deltaType", delta.deltaType)
.put("comparator", comparator.value.toString()) .put("comparator", comparator.value.toString())
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger { override fun fromJSON(data: String): Trigger {
val d = JSONObject(data) 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 com.google.common.base.Optional
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import org.json.JSONObject
// Used for instantiation of other triggers only // Used for instantiation of other triggers only
class TriggerDummy(injector: HasAndroidInjector, val shouldRun: Boolean = false) : Trigger(injector) { class TriggerDummy(injector: HasAndroidInjector, val shouldRun: Boolean = false) : Trigger(injector) {
@ -10,7 +11,7 @@ class TriggerDummy(injector: HasAndroidInjector, val shouldRun: Boolean = false)
return shouldRun return shouldRun
} }
override fun toJSON(): String { override fun dataJSON(): JSONObject {
throw NotImplementedError("An operation is not implemented") throw NotImplementedError("An operation is not implemented")
} }

View file

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

View file

@ -12,6 +12,7 @@ import org.json.JSONObject
import java.text.DecimalFormat import java.text.DecimalFormat
class TriggerLocation(injector: HasAndroidInjector) : Trigger(injector) { class TriggerLocation(injector: HasAndroidInjector) : Trigger(injector) {
var latitude = InputDouble(0.0, -90.0, +90.0, 0.000001, DecimalFormat("0.000000")) 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 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")) 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 return false
} }
override fun toJSON(): String { override fun dataJSON(): JSONObject =
val data = JSONObject() JSONObject()
.put("latitude", latitude.value) .put("latitude", latitude.value)
.put("longitude", longitude.value) .put("longitude", longitude.value)
.put("distance", distance.value) .put("distance", distance.value)
.put("name", name.value) .put("name", name.value)
.put("mode", modeSelected.value) .put("mode", modeSelected.value)
return JSONObject()
.put("type", this::class.java.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Trigger { override fun fromJSON(data: String): Trigger {
val d = JSONObject(data) val d = JSONObject(data)

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -48,7 +48,7 @@ class AutomationEventTest : TestBase() {
event.addAction(ActionLoopEnable(injector)) event.addAction(ActionLoopEnable(injector))
// export to json // 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()) Assert.assertEquals(eventJsonExpected, event.toJSON())
// clone // clone

View file

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

View file

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

View file

@ -88,7 +88,7 @@ class TriggerAutosensValueTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value) 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 @Test
fun toJSONTest() { fun toJSONTest() {

View file

@ -15,7 +15,7 @@ class TriggerBTDeviceTest : TriggerTestBase() {
var now = 1514766900000L var now = 1514766900000L
private var someName = "Headset" 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() { @Test fun shouldRun() {
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")

View file

@ -69,7 +69,7 @@ class TriggerBgTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value) 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 @Test
fun toJSONTest() { fun toJSONTest() {

View file

@ -77,7 +77,7 @@ class TriggerBolusAgoTest : TriggerTestBase() {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value) 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() { @Test fun toJSONTest() {
val t: TriggerBolusAgo = TriggerBolusAgo(injector).setValue(410).comparator(Comparator.Compare.IS_EQUAL) val t: TriggerBolusAgo = TriggerBolusAgo(injector).setValue(410).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(lbJson, t.toJSON()) 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) 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() { @Test fun toJSONTest() {
val t: TriggerCOB = TriggerCOB(injector).setValue(4.0).comparator(Comparator.Compare.IS_EQUAL) val t: TriggerCOB = TriggerCOB(injector).setValue(4.0).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(bgJson, t.toJSON()) Assert.assertEquals(bgJson, t.toJSON())

View file

@ -77,7 +77,7 @@ class TriggerConnectorTest : TriggerTestBase() {
} }
companion object { companion object {
const val empty = "{\"data\":{\"connectorType\":\"AND\",\"triggerList\":[]},\"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\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\"}\"]},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.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) 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 @Test
fun toJSONTest() { fun toJSONTest() {

View file

@ -30,7 +30,7 @@ class TriggerIobTest : TriggerTestBase() {
} }
@Test fun shouldRunTest() { @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) var t: TriggerIob = TriggerIob(injector).setValue(1.1).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertFalse(t.shouldRun()) Assert.assertFalse(t.shouldRun())
t = TriggerIob(injector).setValue(1.0).comparator(Comparator.Compare.IS_EQUAL) 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) 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() { @Test fun toJSONTest() {
val t: TriggerIob = TriggerIob(injector).setValue(4.1).comparator(Comparator.Compare.IS_EQUAL) val t: TriggerIob = TriggerIob(injector).setValue(4.1).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(bgJson, t.toJSON()) Assert.assertEquals(bgJson, t.toJSON())

View file

@ -73,7 +73,7 @@ class TriggerLocationTest : TriggerTestBase() {
// Currently unavailable due to problems with Location mocking // 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() { @Test fun toJSONTest() {
val t = TriggerLocation(injector) val t = TriggerLocation(injector)
t.latitude.setValue(213.0) 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) 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() { @Test fun toJSONTest() {
val t: TriggerProfilePercent = TriggerProfilePercent(injector).setValue(110.0).comparator(Comparator.Compare.IS_EQUAL) val t: TriggerProfilePercent = TriggerProfilePercent(injector).setValue(110.0).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(bgJson, t.toJSON()) 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) 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() { @Test fun toJSONTest() {
val t: TriggerPumpLastConnection = TriggerPumpLastConnection(injector).setValue(410).comparator(Comparator.Compare.IS_EQUAL) val t: TriggerPumpLastConnection = TriggerPumpLastConnection(injector).setValue(410).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(lbJson, t.toJSON()) Assert.assertEquals(lbJson, t.toJSON())

View file

@ -35,7 +35,7 @@ class TriggerRecurringTimeTest : TriggerTestBase() {
Assert.assertTrue(t.shouldRun()) 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 @Test
fun toJSONTest() { fun toJSONTest() {

View file

@ -43,7 +43,7 @@ class TriggerTempTargetTest : TriggerTestBase() {
Assert.assertEquals(ComparatorExists.Compare.NOT_EXISTS, t1.comparator.value) 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() { @Test fun toJSONTest() {
val t: TriggerTempTarget = TriggerTempTarget(injector).comparator(ComparatorExists.Compare.EXISTS) val t: TriggerTempTarget = TriggerTempTarget(injector).comparator(ComparatorExists.Compare.EXISTS)
Assert.assertEquals(ttJson, t.toJSON()) Assert.assertEquals(ttJson, t.toJSON())

View file

@ -18,7 +18,7 @@ import org.powermock.modules.junit4.PowerMockRunner
class TriggerTimeRangeTest : TriggerTestBase() { class TriggerTimeRangeTest : TriggerTestBase() {
var now = 754 // in minutes from midnight 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 @Before
fun mock() { fun mock() {

View file

@ -36,7 +36,7 @@ class TriggerTimeTest : TriggerTestBase() {
Assert.assertFalse(t.shouldRun()) 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() { @Test fun toJSONTest() {
val t: TriggerTime = TriggerTime(injector).runAt(now - T.mins(1).msecs()) val t: TriggerTime = TriggerTime(injector).runAt(now - T.mins(1).msecs())
Assert.assertEquals(timeJson, t.toJSON()) 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) 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() { @Test fun toJSONTest() {
val t: TriggerWifiSsid = TriggerWifiSsid(injector).setValue("aSSID").comparator(Comparator.Compare.IS_EQUAL) val t: TriggerWifiSsid = TriggerWifiSsid(injector).setValue("aSSID").comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(json, t.toJSON()) Assert.assertEquals(json, t.toJSON())

View file

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

View file

@ -16,10 +16,10 @@ abstract class PumpPluginBase(
override fun onStart() { override fun onStart() {
super.onStart() super.onStart()
if (getType() == PluginType.PUMP) { if (getType() == PluginType.PUMP) {
Thread(Runnable { Thread {
SystemClock.sleep(3000) SystemClock.sleep(3000)
commandQueue.readStatus("Pump driver changed.", null) 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 { 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 * GENERAL STATUS
*/ */

View file

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

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.pump package info.nightscout.androidaps.plugins.pump
import info.nightscout.androidaps.core.R
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper 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.interfaces.PumpSync
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag 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.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.DateUtil 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.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign import io.reactivex.rxkotlin.plusAssign
import javax.inject.Inject import javax.inject.Inject
@ -23,12 +30,54 @@ import javax.inject.Inject
class PumpSyncImplementation @Inject constructor( class PumpSyncImplementation @Inject constructor(
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val sp: SP,
private val rxBus: RxBusWrapper,
private val resourceHelper: ResourceHelper,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val repository: AppRepository private val repository: AppRepository
) : PumpSync { ) : PumpSync {
private val disposable = CompositeDisposable() 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 { override fun expectedPumpState(): PumpSync.PumpState {
val bolus = repository.getLastBolusRecord() val bolus = repository.getLastBolusRecord()
val temporaryBasal = repository.getTemporaryBasalActiveAt(dateUtil._now()).blockingGet() 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 { 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( val bolus = Bolus(
timestamp = timestamp, timestamp = timestamp,
amount = amount, 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 { 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( val bolus = Bolus(
timestamp = timestamp, timestamp = timestamp,
amount = amount, 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 { 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( val bolus = Bolus(
timestamp = timestamp, timestamp = timestamp,
amount = amount, amount = amount,
@ -130,6 +182,7 @@ class PumpSyncImplementation @Inject constructor(
} }
override fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean { override fun syncCarbsWithTimestamp(timestamp: Long, amount: Double, pumpId: Long?, pumpType: PumpType, pumpSerial: String): Boolean {
if (!confirmActivePump(timestamp, pumpType, pumpSerial)) return false
val carbs = Carbs( val carbs = Carbs(
timestamp = timestamp, timestamp = timestamp,
amount = amount, 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 { 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( val therapyEvent = TherapyEvent(
timestamp = timestamp, timestamp = timestamp,
type = type.toDBbEventType(), type = type.toDBbEventType(),
@ -175,6 +229,7 @@ class PumpSyncImplementation @Inject constructor(
} }
override fun insertAnnouncement(error: String, pumpId: Long?, pumpType: PumpType, pumpSerial: String) { 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)) disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(error, pumpId, pumpType.toDbPumpType(), pumpSerial))
.subscribe() .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 { 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( val temporaryBasal = TemporaryBasal(
timestamp = timestamp, timestamp = timestamp,
rate = rate, rate = rate,
@ -207,6 +263,7 @@ class PumpSyncImplementation @Inject constructor(
} }
override fun syncStopTemporaryBasalWithPumpId(timestamp: Long, endPumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean { 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)) repository.runTransactionForResult(SyncPumpCancelTemporaryBasalIfAnyTransaction(timestamp, endPumpId, pumpType.toDbPumpType(), pumpSerial))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it) } .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving temporary basal", it) }
.blockingGet() .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 { 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( val extendedBolus = ExtendedBolus(
timestamp = timestamp, timestamp = timestamp,
amount = amount, amount = amount,
@ -253,6 +311,7 @@ class PumpSyncImplementation @Inject constructor(
} }
override fun syncStopExtendedBolusWithPumpId(timestamp: Long, endPumpId: Long, pumpType: PumpType, pumpSerial: String): Boolean { 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)) repository.runTransactionForResult(SyncPumpCancelExtendedBolusIfAnyTransaction(timestamp, endPumpId, pumpType.toDbPumpType(), pumpSerial))
.doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it) } .doOnError { aapsLogger.error(LTag.DATABASE, "Error while saving extended bolus", it) }
.blockingGet() .blockingGet()

View file

@ -33,6 +33,7 @@ object SealedClassHelper {
val x = gson.fromJson<T>(jsonReader, innerClass.javaObjectType) val x = gson.fromJson<T>(jsonReader, innerClass.javaObjectType)
jsonReader.endObject() jsonReader.endObject()
// if there a static object, actually return that // if there a static object, actually return that
@Suppress("UNCHECKED_CAST")
return innerClass.objectInstance as T? ?: x 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_insight_local_settings" translatable="false">insight_local_settings</string>
<string name="key_data_choices_settings" translatable="false">data_choices_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_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--> <!-- General-->
<string name="refresh">Refresh</string> <string name="refresh">Refresh</string>
@ -160,6 +163,7 @@
<string name="notes_label">Notes</string> <string name="notes_label">Notes</string>
<string name="remove_button">Remove</string> <string name="remove_button">Remove</string>
<string name="addnew">Add new</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--> <!-- Constraints-->
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string> <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.setPluginEnabled(PluginType.PUMP, true)
danaRPlugin.setFragmentVisible(PluginType.PUMP, true) danaRPlugin.setFragmentVisible(PluginType.PUMP, true)
danaPump.reset() // mark not initialized danaPump.reset() // mark not initialized
pumpSync.connectNewPump()
//If profile coming from pump, switch it as well //If profile coming from pump, switch it as well
configBuilder.storeSettings("ChangingKoreanDanaDriver") configBuilder.storeSettings("ChangingKoreanDanaDriver")
rxBus.send(EventRebuildTabs()) rxBus.send(EventRebuildTabs())

View file

@ -344,6 +344,58 @@ public class DanaRv2Plugin extends AbstractDanaRPlugin {
return result; 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 @NonNull @Override
public PumpType model() { public PumpType model() {
return PumpType.DANA_RV2; return PumpType.DANA_RV2;

View file

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

View file

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

View file

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

View file

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

View file

@ -16,8 +16,10 @@ class MsgStatusTempBasal(
aapsLogger.debug(LTag.PUMPCOMM, "New message") aapsLogger.debug(LTag.PUMPCOMM, "New message")
} }
var isTempBasalInProgress = false
override fun handleMessage(bytes: ByteArray) { 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 val isAPSTempBasalInProgress = intFromBuff(bytes, 0, 1) and 0x02 == 0x02
var tempBasalPercent = intFromBuff(bytes, 1, 1) var tempBasalPercent = intFromBuff(bytes, 1, 1)
if (tempBasalPercent > 200) tempBasalPercent = (tempBasalPercent - 200) * 10 if (tempBasalPercent > 200) tempBasalPercent = (tempBasalPercent - 200) * 10
@ -47,7 +49,7 @@ class MsgStatusTempBasal(
} }
private fun getDateFromSecAgo(tempBasalAgoSecs: Int): Long { 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 // 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 activePluginProvider: ActivePluginProvider
@Mock lateinit var dateUtil: DateUtil @Mock lateinit var dateUtil: DateUtil
@Mock lateinit var databaseHelper: DatabaseHelperInterface @Mock lateinit var databaseHelper: DatabaseHelperInterface
@Mock lateinit var treatmentsInterface: TreatmentsInterface
@Mock lateinit var danaRPlugin: DanaRPlugin @Mock lateinit var danaRPlugin: DanaRPlugin
@Mock lateinit var danaRKoreanPlugin: DanaRKoreanPlugin @Mock lateinit var danaRKoreanPlugin: DanaRKoreanPlugin
@Mock lateinit var danaRv2Plugin: DanaRv2Plugin @Mock lateinit var danaRv2Plugin: DanaRv2Plugin
@ -49,7 +48,6 @@ open class DanaRTestBase : TestBase() {
fun setup() { fun setup() {
danaPump = DanaPump(aapsLogger, sp, dateUtil, injector) danaPump = DanaPump(aapsLogger, sp, dateUtil, injector)
testPumpPlugin = TestPumpPlugin(injector) testPumpPlugin = TestPumpPlugin(injector)
`when`(activePluginProvider.activeTreatments).thenReturn(treatmentsInterface)
`when`(activePluginProvider.activePump).thenReturn(testPumpPlugin) `when`(activePluginProvider.activePump).thenReturn(testPumpPlugin)
doNothing().`when`(danaRKoreanPlugin).setPluginEnabled(anyObject(), anyBoolean()) doNothing().`when`(danaRKoreanPlugin).setPluginEnabled(anyObject(), anyBoolean())
doNothing().`when`(danaRPlugin).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.Assert
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mockito.Mockito.`when`
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@ -13,10 +12,10 @@ class MsgStatusBolusExtendedTest : DanaRTestBase() {
@Test @Test
fun runTest() { fun runTest() {
`when`(activePluginProvider.activeTreatments).thenReturn(treatmentsInterface)
val packet = MsgStatusBolusExtended(injector) val packet = MsgStatusBolusExtended(injector)
// test message decoding // test message decoding
val array = ByteArray(100) val array = ByteArray(100)
putByteToArray(array, 0, 1)
putByteToArray(array, 1, 1) putByteToArray(array, 1, 1)
packet.handleMessage(array) 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() { @Test fun runTest() {
val packet = MsgStatusTempBasal(injector) val packet = MsgStatusTempBasal(injector)
// test message decoding // test message decoding
// test message decoding
packet.handleMessage(createArray(34, 1.toByte())) packet.handleMessage(createArray(34, 1.toByte()))
Assert.assertEquals(true, danaPump.isTempBasalInProgress) Assert.assertEquals(true, packet.isTempBasalInProgress)
// passing an bigger number // passing an bigger number
packet.handleMessage(createArray(34, 2.toByte())) 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.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") `when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
danaPump = DanaPump(aapsLogger, sp, dateUtil, injector) 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) @Test @Throws(Exception::class)

View file

@ -25,7 +25,7 @@ import org.powermock.core.classloader.annotations.PrepareForTest
import org.powermock.modules.junit4.PowerMockRunner import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class) @PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class)
class DanaRv2PluginTest : TestBaseWithProfile() { class DanaRv2PluginTest : TestBaseWithProfile() {
@Mock lateinit var context: Context @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.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") `when`(resourceHelper.gs(R.string.limitingpercentrate)).thenReturn("Limiting max percent rate to %1\$d%% because of %2\$s")
danaPump = DanaPump(aapsLogger, sp, dateUtil, injector) 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 @Test

View file

@ -19,12 +19,12 @@ class MsgHistoryEventsRv2Test : DanaRTestBase() {
// test message decoding // test message decoding
val array = createArray(100, 2) 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()) putByteToArray(array, 0, 0x01.toByte())
packet.handleMessage(array) packet.handleMessage(array)
Assert.assertEquals(false, danaPump.historyDoneReceived) 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, "") mDeviceAddress = sp.getString(R.string.key_danars_address, "")
mDeviceName = sp.getString(R.string.key_danars_name, "") mDeviceName = sp.getString(R.string.key_danars_name, "")
danaPump.reset() danaPump.reset()
pumpSync.connectNewPump()
commandQueue.readStatus("DeviceChanged", null) 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") 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) { override fun handleMessage(data: ByteArray) {
val error = byteArrayToInt(getBytes(data, DATA_START, 1)) 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 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 if (tempBasalPercent > 200) tempBasalPercent = (tempBasalPercent - 200) * 10
val durationHour = byteArrayToInt(getBytes(data, DATA_START + 3, 1)) 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)) val runningMin = byteArrayToInt(getBytes(data, DATA_START + 4, 2))
if (error != 0) failed = true if (error != 0) failed = true
val tempBasalRemainingMin = (danaPump.tempBasalTotalSec - runningMin * 60) / 60 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") aapsLogger.debug(LTag.PUMPCOMM, "New message")
} }
var isExtendedInProgress: Boolean = false
override fun handleMessage(data: ByteArray) { override fun handleMessage(data: ByteArray) {
var dataIndex = DATA_START var dataIndex = DATA_START
var dataSize = 1 var dataSize = 1
val error = byteArrayToInt(getBytes(data, dataIndex, dataSize)) val error = byteArrayToInt(getBytes(data, dataIndex, dataSize))
dataIndex += dataSize dataIndex += dataSize
dataSize = 1 dataSize = 1
val isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01 isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01
dataIndex += dataSize dataIndex += dataSize
dataSize = 1 dataSize = 1
val extendedBolusDuration = T.mins(byteArrayToInt(getBytes(data, dataIndex, dataSize)) * 30L).msecs() 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") aapsLogger.debug(LTag.PUMPCOMM, "New message")
} }
var isExtendedInProgress: Boolean = false
override fun handleMessage(data: ByteArray) { override fun handleMessage(data: ByteArray) {
var dataIndex = DATA_START var dataIndex = DATA_START
var dataSize = 1 var dataSize = 1
val extendedMenuOption = byteArrayToInt(getBytes(data, dataIndex, dataSize)) val extendedMenuOption = byteArrayToInt(getBytes(data, dataIndex, dataSize))
dataIndex += dataSize dataIndex += dataSize
dataSize = 1 dataSize = 1
val isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01 isExtendedInProgress = byteArrayToInt(getBytes(data, dataIndex, dataSize)) == 0x01
aapsLogger.debug(LTag.PUMPCOMM, "extendedMenuOption: $extendedMenuOption") aapsLogger.debug(LTag.PUMPCOMM, "extendedMenuOption: $extendedMenuOption")
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -33,7 +33,6 @@ class DanaRsPacketBolusGetDualBolusTest : DanaRSTestBase() {
packet.handleMessage(array) packet.handleMessage(array)
Assert.assertTrue(packet.failed) Assert.assertTrue(packet.failed)
Assert.assertEquals(1.0, danaPump.bolusStep, 0.0) 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(40.0, danaPump.maxBolus, 0.0)
Assert.assertEquals("BOLUS__GET_DUAL_BOLUS", packet.friendlyName) Assert.assertEquals("BOLUS__GET_DUAL_BOLUS", packet.friendlyName)

View file

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

View file

@ -26,10 +26,10 @@ class DanaRsPacketBolusGetExtendedMenuOptionStateTest : DanaRSTestBase() {
// test message decoding // test message decoding
packet.handleMessage(createArray(34, 0.toByte())) packet.handleMessage(createArray(34, 0.toByte()))
// isExtendedInProgress should be false // isExtendedInProgress should be false
Assert.assertEquals(false, danaPump.isExtendedInProgress) Assert.assertEquals(false, packet.isExtendedInProgress)
// assertEquals(false, packet.failed); // assertEquals(false, packet.failed);
packet.handleMessage(createArray(34, 1.toByte())) 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) 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 import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class) @PrepareForTest(ConstraintChecker::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class)
class DanaRsPacketBolusSetStepBolusStartTest : DanaRSTestBase() { class DanaRsPacketBolusSetStepBolusStartTest : DanaRSTestBase() {
@Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var constraintChecker: ConstraintChecker

View file

@ -44,8 +44,6 @@ class DanaRsPacketGeneralGetMoreInformationTest : DanaRSTestBase() {
Assert.assertFalse(packet.failed) Assert.assertFalse(packet.failed)
Assert.assertEquals(6.0, danaPump.iob, 0.01) Assert.assertEquals(6.0, danaPump.iob, 0.01)
Assert.assertEquals(12.5, danaPump.dailyTotalUnits, 0.01) Assert.assertEquals(12.5, danaPump.dailyTotalUnits, 0.01)
Assert.assertTrue(danaPump.isExtendedInProgress)
Assert.assertEquals(150, danaPump.extendedBolusRemainingMinutes)
val lastBolus = Calendar.getInstance() val lastBolus = Calendar.getInstance()
lastBolus.timeInMillis = danaPump.lastBolusTime lastBolus.timeInMillis = danaPump.lastBolusTime
Assert.assertEquals(15, lastBolus.get(Calendar.HOUR_OF_DAY)) 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 import org.powermock.modules.junit4.PowerMockRunner
@RunWith(PowerMockRunner::class) @RunWith(PowerMockRunner::class)
@PrepareForTest(ConstraintChecker::class, RxBusWrapper::class, DetailedBolusInfoStorage::class) @PrepareForTest(ConstraintChecker::class, RxBusWrapper::class, DetailedBolusInfoStorage::class, TemporaryBasalStorage::class)
class DanaRsPacketNotifyDeliveryRateDisplayTest : DanaRSTestBase() { class DanaRsPacketNotifyDeliveryRateDisplayTest : DanaRSTestBase() {
@Mock lateinit var activePlugin: ActivePluginProvider @Mock lateinit var activePlugin: ActivePluginProvider

View file

@ -33,6 +33,7 @@ object SealedClassHelper {
val x = gson.fromJson<T>(jsonReader, innerClass.javaObjectType) val x = gson.fromJson<T>(jsonReader, innerClass.javaObjectType)
jsonReader.endObject() jsonReader.endObject()
// if there a static object, actually return that // if there a static object, actually return that
@Suppress("UNCHECKED_CAST")
return innerClass.objectInstance as T? ?: x 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, OmnipodErosPumpPlugin plugin = new OmnipodErosPumpPlugin(injector, aapsLogger, new TestAapsSchedulers(), rxBusWrapper, null,
resourceHelper, activePluginProvider, null, null, aapsOmnipodErosManager, commandQueueProvider, resourceHelper, activePluginProvider, null, null, aapsOmnipodErosManager, commandQueueProvider,
null, null, null, null, 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(rileyLinkUtil.getRileyLinkHistory()).thenReturn(new ArrayList<>());
when(injector.androidInjector()).thenReturn(instance -> { when(injector.androidInjector()).thenReturn(instance -> {
}); });