check for invalid actions

This commit is contained in:
Milos Kozak 2021-02-03 12:57:33 +01:00
parent bfd33502e6
commit dbb2234236
18 changed files with 78 additions and 25 deletions

View file

@ -43,6 +43,12 @@ class AutomationEvent(private val injector: HasAndroidInjector) {
fun addAction(action: Action) = actions.add(action)
fun areActionsValid() : Boolean {
var result = true
for (action in actions) result = result && action.isValid()
return result
}
fun toJSON(): String {
val array = JSONArray()
for (a in actions) array.put(a.toJSON())

View file

@ -162,6 +162,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
@SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val event = automationPlugin.at(position)
holder.binding.rootLayout.setBackgroundColor(resourceHelper.gc(if (event.areActionsValid()) R.color.ribbonDefault else R.color.errorAlertBackground))
holder.binding.eventTitle.text = event.title
holder.binding.enabled.isChecked = event.isEnabled
holder.binding.enabled.isEnabled = !event.readOnly

View file

@ -200,30 +200,36 @@ class AutomationPlugin @Inject constructor(
}
aapsLogger.debug(LTag.AUTOMATION, "processActions")
val iterator : MutableIterator<AutomationEvent> = automationEvents.iterator()
val iterator: MutableIterator<AutomationEvent> = automationEvents.iterator()
while (iterator.hasNext()) {
val event = iterator.next()
if (event.isEnabled && event.shouldRun() && event.trigger.shouldRun() && event.getPreconditions().shouldRun()) {
if (event.systemAction || userEventsEnabled) {
val actions = event.actions
for (action in actions) {
action.doAction(object : Callback() {
override fun run() {
val sb = StringBuilder()
sb.append(dateUtil.timeString(DateUtil.now()))
sb.append(" ")
sb.append(if (result.success) "" else "")
sb.append(" <b>")
sb.append(event.title)
sb.append(":</b> ")
sb.append(action.shortDescription())
sb.append(": ")
sb.append(result.comment)
executionLog.add(sb.toString())
aapsLogger.debug(LTag.AUTOMATION, "Executed: $sb")
rxBus.send(EventAutomationUpdateGui())
}
})
if (action.isValid())
action.doAction(object : Callback() {
override fun run() {
val sb = StringBuilder()
sb.append(dateUtil.timeString(DateUtil.now()))
sb.append(" ")
sb.append(if (result.success) "" else "")
sb.append(" <b>")
sb.append(event.title)
sb.append(":</b> ")
sb.append(action.shortDescription())
sb.append(": ")
sb.append(result.comment)
executionLog.add(sb.toString())
aapsLogger.debug(LTag.AUTOMATION, "Executed: $sb")
rxBus.send(EventAutomationUpdateGui())
}
})
else {
executionLog.add("Invalid action: ${action.shortDescription()}")
aapsLogger.debug(LTag.AUTOMATION, "Invalid action: ${action.shortDescription()}")
rxBus.send(EventAutomationUpdateGui())
}
}
SystemClock.sleep(1100)
event.lastRun = DateUtil.now()

View file

@ -12,6 +12,7 @@ import javax.inject.Inject
import kotlin.reflect.full.primaryConstructor
abstract class Action(val injector: HasAndroidInjector) {
@Inject lateinit var aapsLogger: AAPSLogger
var precondition: Trigger? = null
@ -19,6 +20,7 @@ abstract class Action(val injector: HasAndroidInjector) {
abstract fun friendlyName(): Int
abstract fun shortDescription(): String
abstract fun doAction(callback: Callback)
abstract fun isValid(): Boolean
@DrawableRes abstract fun icon(): Int
init {

View file

@ -40,6 +40,8 @@ class ActionAlarm(injector: HasAndroidInjector) : Action(injector) {
override fun shortDescription(): String = resourceHelper.gs(R.string.alarm_message, text.value)
@DrawableRes override fun icon(): Int = R.drawable.ic_access_alarm_24dp
override fun isValid(): Boolean = text.value.isNotEmpty()
override fun doAction(callback: Callback) {
val i = Intent(context, ErrorHelperActivity::class.java)
i.putExtra("soundid", R.raw.modern_alarm)

View file

@ -18,6 +18,8 @@ class ActionDummy(injector: HasAndroidInjector) : Action(injector) {
throw NotImplementedError("An operation is not implemented")
}
override fun isValid(): Boolean = false
override fun icon(): Int {
throw NotImplementedError("An operation is not implemented")
}

View file

@ -39,4 +39,6 @@ class ActionLoopDisable(injector: HasAndroidInjector) : Action(injector) {
callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadydisabled)).run()
}
}
override fun isValid(): Boolean = true
}

View file

@ -14,6 +14,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
class ActionLoopEnable(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var loopPlugin: LoopPlugin
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@ -34,4 +35,5 @@ class ActionLoopEnable(injector: HasAndroidInjector) : Action(injector) {
}
}
override fun isValid(): Boolean = true
}

View file

@ -33,4 +33,6 @@ class ActionLoopResume(injector: HasAndroidInjector) : Action(injector) {
callback.result(PumpEnactResult(injector).success(true).comment(R.string.notsuspended))?.run()
}
}
override fun isValid(): Boolean = true
}

View file

@ -22,7 +22,7 @@ class ActionLoopSuspend(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var loopPlugin: LoopPlugin
@Inject lateinit var rxBus: RxBusWrapper
var minutes = InputDuration(injector, 0, InputDuration.TimeUnit.MINUTES)
var minutes = InputDuration(injector, 30, InputDuration.TimeUnit.MINUTES)
override fun friendlyName(): Int = R.string.suspendloop
override fun shortDescription(): String = resourceHelper.gs(R.string.suspendloopforXmin, minutes.getMinutes())
@ -59,4 +59,6 @@ class ActionLoopSuspend(injector: HasAndroidInjector) : Action(injector) {
.add(LabelWithElement(injector, resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", minutes))
.build(root)
}
override fun isValid(): Boolean = minutes.value > 5
}

View file

@ -59,4 +59,6 @@ class ActionNotification(injector: HasAndroidInjector) : Action(injector) {
.add(LabelWithElement(injector, resourceHelper.gs(R.string.message_short), "", text))
.build(root)
}
override fun isValid(): Boolean = text.value.isNotEmpty()
}

View file

@ -78,4 +78,6 @@ class ActionProfileSwitch(injector: HasAndroidInjector) : Action(injector) {
inputProfileName.value = JsonHelper.safeGetString(o, "profileToSwitchTo", "")
return this
}
override fun isValid(): Boolean = activePlugin.activeProfileInterface.profile?.getSpecificProfile(inputProfileName.value) != null
}

View file

@ -23,7 +23,7 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector
@Inject lateinit var activePlugin: ActivePluginProvider
var pct = InputPercent(injector)
var duration = InputDuration(injector, 0, InputDuration.TimeUnit.MINUTES)
var duration = InputDuration(injector, 30, InputDuration.TimeUnit.MINUTES)
override fun friendlyName(): Int = R.string.profilepercentage
override fun shortDescription(): String =
@ -66,4 +66,9 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector
duration.value = JsonHelper.safeGetInt(o, "durationInMinutes")
return this
}
override fun isValid(): Boolean =
pct.value >= InputPercent.MIN &&
pct.value <= InputPercent.MAX &&
duration.value > 0
}

View file

@ -15,6 +15,7 @@ import org.json.JSONObject
import javax.inject.Inject
class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
@ -29,6 +30,8 @@ class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) {
callback.result(PumpEnactResult(injector).success(result).comment(if (result) R.string.ok else R.string.error))?.run()
}
override fun isValid(): Boolean = text.value.isNotEmpty()
override fun toJSON(): String {
val data = JSONObject().put("text", text.value)
return JSONObject()

View file

@ -25,11 +25,12 @@ import org.json.JSONObject
import javax.inject.Inject
class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var activePlugin: ActivePluginProvider
var value = InputTempTarget(injector)
var duration = InputDuration(injector, 0, InputDuration.TimeUnit.MINUTES)
var duration = InputDuration(injector, 30, InputDuration.TimeUnit.MINUTES)
init {
precondition = TriggerTempTarget(injector, ComparatorExists.Compare.NOT_EXISTS)
@ -83,4 +84,15 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
.source(Source.USER)
.low(Profile.toMgdl(value.value, value.units))
.high(Profile.toMgdl(value.value, value.units))
override fun isValid(): Boolean =
if (value.units == Constants.MMOL) { // mmol
value.value >= Constants.MIN_TT_MMOL &&
value.value <= Constants.MAX_TT_MMOL &&
duration.value > 0
} else { // mg/dL
value.value >= Constants.MIN_TT_MGDL &&
value.value <= Constants.MAX_TT_MGDL &&
duration.value > 0
}
}

View file

@ -12,6 +12,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
import javax.inject.Inject
class ActionStopTempTarget(injector: HasAndroidInjector) : Action(injector) {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var activePlugin: ActivePluginProvider
@ -29,4 +30,6 @@ class ActionStopTempTarget(injector: HasAndroidInjector) : Action(injector) {
activePlugin.activeTreatments.addToHistoryTempTarget(tempTarget)
callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run()
}
override fun isValid(): Boolean = true
}

View file

@ -24,12 +24,11 @@ class InputDuration(injector: HasAndroidInjector) : Element(injector) {
val numberPicker : NumberPicker
if (unit == TimeUnit.MINUTES) {
numberPicker = MinutesNumberPicker(root.context, null)
numberPicker.setParams(0.0, 0.0, 24 * 60.0, 10.0, DecimalFormat("0"), false, root.findViewById(R.id.ok))
numberPicker.setParams(value.toDouble(), 5.0, 24 * 60.0, 10.0, DecimalFormat("0"), false, root.findViewById(R.id.ok))
} else {
numberPicker = NumberPicker(root.context, null)
numberPicker.setParams(0.0, 0.0, 24.0, 1.0, DecimalFormat("0"), false, root.findViewById(R.id.ok))
numberPicker.setParams(value.toDouble(), 1.0, 24.0, 1.0, DecimalFormat("0"), false, root.findViewById(R.id.ok))
}
numberPicker.value = value.toDouble()
numberPicker.setOnValueChangedListener { value: Double -> this.value = value.toInt() }
root.addView(numberPicker)
}

View file

@ -16,7 +16,7 @@ import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import org.json.JSONObject
class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) {
var minutesAgo: InputDuration = InputDuration(injector, 0, InputDuration.TimeUnit.MINUTES)
var minutesAgo: InputDuration = InputDuration(injector, 30, InputDuration.TimeUnit.MINUTES)
var comparator: Comparator = Comparator(injector)
private constructor(injector: HasAndroidInjector, triggerBolusAgo: TriggerBolusAgo) : this(injector) {