Merge branch 'Fix/TriggerTempTargetValue' into dev

This commit is contained in:
Milos Kozak 2021-10-03 12:31:18 +02:00
commit ff9e1fb931
7 changed files with 194 additions and 0 deletions

View file

@ -27,6 +27,7 @@ abstract class AutomationModule {
@ContributesAndroidInjector abstract fun triggerBTDeviceInjector(): TriggerBTDevice @ContributesAndroidInjector abstract fun triggerBTDeviceInjector(): TriggerBTDevice
@ContributesAndroidInjector abstract fun triggerRecurringTimeInjector(): TriggerRecurringTime @ContributesAndroidInjector abstract fun triggerRecurringTimeInjector(): TriggerRecurringTime
@ContributesAndroidInjector abstract fun triggerTempTargetInjector(): TriggerTempTarget @ContributesAndroidInjector abstract fun triggerTempTargetInjector(): TriggerTempTarget
@ContributesAndroidInjector abstract fun triggerTempTargetValueInjector(): TriggerTempTargetValue
@ContributesAndroidInjector abstract fun triggerTime(): TriggerTime @ContributesAndroidInjector abstract fun triggerTime(): TriggerTime
@ContributesAndroidInjector abstract fun triggerTimeRangeInjector(): TriggerTimeRange @ContributesAndroidInjector abstract fun triggerTimeRangeInjector(): TriggerTimeRange
@ContributesAndroidInjector abstract fun triggerWifiSsidInjector(): TriggerWifiSsid @ContributesAndroidInjector abstract fun triggerWifiSsidInjector(): TriggerWifiSsid

View file

@ -311,6 +311,7 @@ class AutomationPlugin @Inject constructor(
TriggerCOB(injector), TriggerCOB(injector),
TriggerProfilePercent(injector), TriggerProfilePercent(injector),
TriggerTempTarget(injector), TriggerTempTarget(injector),
TriggerTempTargetValue(injector),
TriggerWifiSsid(injector), TriggerWifiSsid(injector),
TriggerLocation(injector), TriggerLocation(injector),
TriggerAutosensValue(injector), TriggerAutosensValue(injector),

View file

@ -131,6 +131,10 @@ abstract class Trigger(val injector: HasAndroidInjector) {
TriggerTempTarget::class.java.simpleName -> TriggerTempTarget(injector).fromJSON( TriggerTempTarget::class.java.simpleName -> TriggerTempTarget(injector).fromJSON(
data.toString() data.toString()
) )
TriggerTempTargetValue::class.java.name,
TriggerTempTargetValue::class.java.simpleName -> TriggerTempTargetValue(injector).fromJSON(
data.toString()
)
TriggerTime::class.java.name, TriggerTime::class.java.name,
TriggerTime::class.java.simpleName -> TriggerTime(injector).fromJSON(data.toString()) TriggerTime::class.java.simpleName -> TriggerTime(injector).fromJSON(data.toString())
TriggerTimeRange::class.java.name, TriggerTimeRange::class.java.name,

View file

@ -0,0 +1,98 @@
package info.nightscout.androidaps.plugins.general.automation.triggers
import android.widget.LinearLayout
import com.google.common.base.Optional
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
import info.nightscout.androidaps.plugins.general.automation.elements.InputBg
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
class TriggerTempTargetValue(injector: HasAndroidInjector) : Trigger(injector) {
var ttValue = InputBg(profileFunction)
var comparator = Comparator(resourceHelper)
constructor(injector: HasAndroidInjector, value: Double, units: GlucoseUnit, compare: Comparator.Compare) : this(injector) {
ttValue = InputBg(profileFunction, value, units)
comparator = Comparator(resourceHelper, compare)
}
constructor(injector: HasAndroidInjector, triggerTempTarget: TriggerTempTargetValue) : this(injector) {
ttValue = InputBg(profileFunction, triggerTempTarget.ttValue.value, triggerTempTarget.ttValue.units)
comparator = Comparator(resourceHelper, triggerTempTarget.comparator.value)
}
fun comparator(comparator: Comparator.Compare): TriggerTempTargetValue {
this.comparator.value = comparator
return this
}
fun setUnits(units: GlucoseUnit): TriggerTempTargetValue {
ttValue.units = units
return this
}
fun setValue(value: Double): TriggerTempTargetValue {
ttValue.value = value
return this
}
override fun shouldRun(): Boolean {
val tt = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
if (tt is ValueWrapper.Absent && comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true
}
if (tt is ValueWrapper.Existing && comparator.value.check(tt.value.lowTarget, Profile.toMgdl(ttValue.value, ttValue.units))) {
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
return true
}
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
return false
}
override fun dataJSON(): JSONObject =
JSONObject()
.put("tt", ttValue.value)
.put("comparator", comparator.value.toString())
.put("units", ttValue.units.asText)
override fun fromJSON(data: String): Trigger {
val d = JSONObject(data)
ttValue.setUnits(GlucoseUnit.fromText(JsonHelper.safeGetString(d, "units", Constants.MGDL)))
ttValue.value = JsonHelper.safeGetDouble(d, "tt")
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!))
return this
}
override fun friendlyName(): Int = R.string.careportal_temporarytargetvalue
override fun friendlyDescription(): String {
return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE)
resourceHelper.gs(R.string.notemptarget)
else
resourceHelper.gs(if (ttValue.units == GlucoseUnit.MGDL) R.string.temptargetcomparedmgdl else R.string.temptargetcomparedmmol, resourceHelper.gs(comparator.value.stringRes), ttValue.value, ttValue.units)
}
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_keyboard_tab)
override fun duplicate(): Trigger = TriggerTempTargetValue(injector, this)
override fun generateDialog(root: LinearLayout) {
LayoutBuilder()
.add(StaticLabel(resourceHelper, R.string.careportal_temporarytargetvalue, this))
.add(comparator)
.add(LabelWithElement(resourceHelper, resourceHelper.gs(R.string.target_u, ttValue.units), "", ttValue))
.build(root)
}
}

View file

@ -40,6 +40,9 @@
<string name="glucoseisnotavailable">Glucose is not available</string> <string name="glucoseisnotavailable">Glucose is not available</string>
<string name="glucosecomparedmgdl">Glucose %1$s %2$.0f %3$s</string> <string name="glucosecomparedmgdl">Glucose %1$s %2$.0f %3$s</string>
<string name="glucosecomparedmmol">Glucose %1$s %2$.1f %3$s</string> <string name="glucosecomparedmmol">Glucose %1$s %2$.1f %3$s</string>
<string name="notemptarget">Temp Target does not exist</string>
<string name="temptargetcomparedmgdl">Temp Target %1$s %2$.0f %3$s</string>
<string name="temptargetcomparedmmol">Temp Target %1$s %2$.1f %3$s</string>
<string name="percentagecompared">Profile pct %1$s %2$d</string> <string name="percentagecompared">Profile pct %1$s %2$d</string>
<string name="iobcompared">IOB %1$s %2$.1f</string> <string name="iobcompared">IOB %1$s %2$.1f</string>
<string name="and">And</string> <string name="and">And</string>
@ -88,6 +91,7 @@
<string name="latitude_short">Lat:</string> <string name="latitude_short">Lat:</string>
<string name="longitude_short">Lon:</string> <string name="longitude_short">Lon:</string>
<string name="glucose_u">Glucose [%1$s]:</string> <string name="glucose_u">Glucose [%1$s]:</string>
<string name="target_u">Target [%1$s]:</string>
<string name="lastboluslabel">Last bolus ago</string> <string name="lastboluslabel">Last bolus ago</string>
<string name="lastboluscompared">Last bolus time %1$s %2$s min ago</string> <string name="lastboluscompared">Last bolus time %1$s %2$s min ago</string>
<string name="triggercoblabel">COB</string> <string name="triggercoblabel">COB</string>

View file

@ -0,0 +1,85 @@
package info.nightscout.androidaps.plugins.general.automation.triggers
import com.google.common.base.Optional
import info.nightscout.androidaps.automation.R
import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.TemporaryTarget
import info.nightscout.androidaps.interfaces.GlucoseUnit
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
import io.reactivex.Single
import org.json.JSONObject
import org.junit.Assert
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito.`when`
class TriggerTempTargetValueTest : TriggerTestBase() {
var now = 1514766900000L
@Before
fun prepare() {
`when`(profileFunction.getUnits()).thenReturn(GlucoseUnit.MGDL)
`when`(dateUtil.now()).thenReturn(now)
}
@Test
fun shouldRunTest() {
`when`(repository.getTemporaryTargetActiveAt(dateUtil.now())).thenReturn(Single.just(ValueWrapper.Existing(TemporaryTarget(duration = 60000, highTarget = 140.0, lowTarget = 140.0, reason = TemporaryTarget.Reason.CUSTOM, timestamp = now - 1))))
var t: TriggerTempTargetValue = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MMOL).setValue(7.7).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertFalse(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(140.0).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertTrue(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(140.0).comparator(Comparator.Compare.IS_EQUAL_OR_GREATER)
Assert.assertTrue(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(140.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
Assert.assertTrue(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(139.0).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertFalse(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(141.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
Assert.assertTrue(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(141.0).comparator(Comparator.Compare.IS_EQUAL_OR_GREATER)
Assert.assertFalse(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(139.0).comparator(Comparator.Compare.IS_EQUAL_OR_GREATER)
Assert.assertTrue(t.shouldRun())
t = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(139.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
Assert.assertFalse(t.shouldRun())
Assert.assertFalse(t.shouldRun())
t = TriggerTempTargetValue(injector).comparator(Comparator.Compare.IS_NOT_AVAILABLE)
Assert.assertFalse(t.shouldRun())
`when`(repository.getTemporaryTargetActiveAt(dateUtil.now())).thenReturn(Single.just(ValueWrapper.Absent()))
Assert.assertTrue(t.shouldRun())
}
@Test
fun copyConstructorTest() {
val t: TriggerTempTargetValue = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MGDL).setValue(140.0).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER)
val t1 = t.duplicate() as TriggerTempTargetValue
Assert.assertEquals(140.0, t1.ttValue.value, 0.01)
Assert.assertEquals(GlucoseUnit.MGDL, t1.ttValue.units)
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.comparator.value)
}
private var ttJson = "{\"data\":{\"tt\":7.7,\"comparator\":\"IS_EQUAL\",\"units\":\"mmol\"},\"type\":\"TriggerTempTargetValue\"}"
@Test
fun toJSONTest() {
val t: TriggerTempTargetValue = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MMOL).setValue(7.7).comparator(Comparator.Compare.IS_EQUAL)
Assert.assertEquals(ttJson, t.toJSON())
}
@Test
fun fromJSONTest() {
val t: TriggerTempTargetValue = TriggerTempTargetValue(injector).setUnits(GlucoseUnit.MMOL).setValue(7.7).comparator(Comparator.Compare.IS_EQUAL)
val t2 = TriggerDummy(injector).instantiate(JSONObject(t.toJSON())) as TriggerTempTargetValue
Assert.assertEquals(Comparator.Compare.IS_EQUAL, t2.comparator.value)
Assert.assertEquals(7.7, t2.ttValue.value, 0.01)
Assert.assertEquals(GlucoseUnit.MMOL, t2.ttValue.units)
}
@Test
fun iconTest() {
Assert.assertEquals(Optional.of(R.drawable.ic_keyboard_tab), TriggerTempTargetValue(injector).icon())
}
}

View file

@ -272,6 +272,7 @@
<string name="careportal_openapsoffline">OpenAPS Offline</string> <string name="careportal_openapsoffline">OpenAPS Offline</string>
<string name="careportal_pumpbatterychange">Pump Battery Change</string> <string name="careportal_pumpbatterychange">Pump Battery Change</string>
<string name="careportal_temporarytarget">Temporary target</string> <string name="careportal_temporarytarget">Temporary target</string>
<string name="careportal_temporarytargetvalue">Temporary target value</string>
<string name="careportal_temporarytargetcancel">Temporary target cancel</string> <string name="careportal_temporarytargetcancel">Temporary target cancel</string>
<string name="boluswizard">Bolus wizard</string> <string name="boluswizard">Bolus wizard</string>
<string name="glucosetype_finger">Finger</string> <string name="glucosetype_finger">Finger</string>