check for invalid actions
This commit is contained in:
parent
bfd33502e6
commit
dbb2234236
18 changed files with 78 additions and 25 deletions
|
@ -43,6 +43,12 @@ class AutomationEvent(private val injector: HasAndroidInjector) {
|
||||||
|
|
||||||
fun addAction(action: Action) = actions.add(action)
|
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 {
|
fun toJSON(): String {
|
||||||
val array = JSONArray()
|
val array = JSONArray()
|
||||||
for (a in actions) array.put(a.toJSON())
|
for (a in actions) array.put(a.toJSON())
|
||||||
|
|
|
@ -162,6 +162,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val event = automationPlugin.at(position)
|
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.eventTitle.text = event.title
|
||||||
holder.binding.enabled.isChecked = event.isEnabled
|
holder.binding.enabled.isChecked = event.isEnabled
|
||||||
holder.binding.enabled.isEnabled = !event.readOnly
|
holder.binding.enabled.isEnabled = !event.readOnly
|
||||||
|
|
|
@ -200,30 +200,36 @@ class AutomationPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
aapsLogger.debug(LTag.AUTOMATION, "processActions")
|
aapsLogger.debug(LTag.AUTOMATION, "processActions")
|
||||||
val iterator : MutableIterator<AutomationEvent> = automationEvents.iterator()
|
val iterator: MutableIterator<AutomationEvent> = automationEvents.iterator()
|
||||||
while (iterator.hasNext()) {
|
while (iterator.hasNext()) {
|
||||||
val event = iterator.next()
|
val event = iterator.next()
|
||||||
if (event.isEnabled && event.shouldRun() && event.trigger.shouldRun() && event.getPreconditions().shouldRun()) {
|
if (event.isEnabled && event.shouldRun() && event.trigger.shouldRun() && event.getPreconditions().shouldRun()) {
|
||||||
if (event.systemAction || userEventsEnabled) {
|
if (event.systemAction || userEventsEnabled) {
|
||||||
val actions = event.actions
|
val actions = event.actions
|
||||||
for (action in actions) {
|
for (action in actions) {
|
||||||
action.doAction(object : Callback() {
|
if (action.isValid())
|
||||||
override fun run() {
|
action.doAction(object : Callback() {
|
||||||
val sb = StringBuilder()
|
override fun run() {
|
||||||
sb.append(dateUtil.timeString(DateUtil.now()))
|
val sb = StringBuilder()
|
||||||
sb.append(" ")
|
sb.append(dateUtil.timeString(DateUtil.now()))
|
||||||
sb.append(if (result.success) "☺" else "▼")
|
sb.append(" ")
|
||||||
sb.append(" <b>")
|
sb.append(if (result.success) "☺" else "▼")
|
||||||
sb.append(event.title)
|
sb.append(" <b>")
|
||||||
sb.append(":</b> ")
|
sb.append(event.title)
|
||||||
sb.append(action.shortDescription())
|
sb.append(":</b> ")
|
||||||
sb.append(": ")
|
sb.append(action.shortDescription())
|
||||||
sb.append(result.comment)
|
sb.append(": ")
|
||||||
executionLog.add(sb.toString())
|
sb.append(result.comment)
|
||||||
aapsLogger.debug(LTag.AUTOMATION, "Executed: $sb")
|
executionLog.add(sb.toString())
|
||||||
rxBus.send(EventAutomationUpdateGui())
|
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)
|
SystemClock.sleep(1100)
|
||||||
event.lastRun = DateUtil.now()
|
event.lastRun = DateUtil.now()
|
||||||
|
|
|
@ -12,6 +12,7 @@ import javax.inject.Inject
|
||||||
import kotlin.reflect.full.primaryConstructor
|
import kotlin.reflect.full.primaryConstructor
|
||||||
|
|
||||||
abstract class Action(val injector: HasAndroidInjector) {
|
abstract class Action(val injector: HasAndroidInjector) {
|
||||||
|
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
|
||||||
var precondition: Trigger? = null
|
var precondition: Trigger? = null
|
||||||
|
@ -19,6 +20,7 @@ abstract class Action(val injector: HasAndroidInjector) {
|
||||||
abstract fun friendlyName(): Int
|
abstract fun friendlyName(): Int
|
||||||
abstract fun shortDescription(): String
|
abstract fun shortDescription(): String
|
||||||
abstract fun doAction(callback: Callback)
|
abstract fun doAction(callback: Callback)
|
||||||
|
abstract fun isValid(): Boolean
|
||||||
@DrawableRes abstract fun icon(): Int
|
@DrawableRes abstract fun icon(): Int
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
|
@ -40,6 +40,8 @@ class ActionAlarm(injector: HasAndroidInjector) : Action(injector) {
|
||||||
override fun shortDescription(): String = resourceHelper.gs(R.string.alarm_message, text.value)
|
override fun shortDescription(): String = resourceHelper.gs(R.string.alarm_message, text.value)
|
||||||
@DrawableRes override fun icon(): Int = R.drawable.ic_access_alarm_24dp
|
@DrawableRes override fun icon(): Int = R.drawable.ic_access_alarm_24dp
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = text.value.isNotEmpty()
|
||||||
|
|
||||||
override fun doAction(callback: Callback) {
|
override fun doAction(callback: Callback) {
|
||||||
val i = Intent(context, ErrorHelperActivity::class.java)
|
val i = Intent(context, ErrorHelperActivity::class.java)
|
||||||
i.putExtra("soundid", R.raw.modern_alarm)
|
i.putExtra("soundid", R.raw.modern_alarm)
|
||||||
|
|
|
@ -18,6 +18,8 @@ class ActionDummy(injector: HasAndroidInjector) : Action(injector) {
|
||||||
throw NotImplementedError("An operation is not implemented")
|
throw NotImplementedError("An operation is not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = false
|
||||||
|
|
||||||
override fun icon(): Int {
|
override fun icon(): Int {
|
||||||
throw NotImplementedError("An operation is not implemented")
|
throw NotImplementedError("An operation is not implemented")
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,4 +39,6 @@ class ActionLoopDisable(injector: HasAndroidInjector) : Action(injector) {
|
||||||
callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadydisabled)).run()
|
callback.result(PumpEnactResult(injector).success(true).comment(R.string.alreadydisabled)).run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = true
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ActionLoopEnable(injector: HasAndroidInjector) : Action(injector) {
|
class ActionLoopEnable(injector: HasAndroidInjector) : Action(injector) {
|
||||||
|
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var loopPlugin: LoopPlugin
|
@Inject lateinit var loopPlugin: LoopPlugin
|
||||||
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
|
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
|
||||||
|
@ -34,4 +35,5 @@ class ActionLoopEnable(injector: HasAndroidInjector) : Action(injector) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = true
|
||||||
}
|
}
|
|
@ -33,4 +33,6 @@ class ActionLoopResume(injector: HasAndroidInjector) : Action(injector) {
|
||||||
callback.result(PumpEnactResult(injector).success(true).comment(R.string.notsuspended))?.run()
|
callback.result(PumpEnactResult(injector).success(true).comment(R.string.notsuspended))?.run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = true
|
||||||
}
|
}
|
|
@ -22,7 +22,7 @@ class ActionLoopSuspend(injector: HasAndroidInjector) : Action(injector) {
|
||||||
@Inject lateinit var loopPlugin: LoopPlugin
|
@Inject lateinit var loopPlugin: LoopPlugin
|
||||||
@Inject lateinit var rxBus: RxBusWrapper
|
@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 friendlyName(): Int = R.string.suspendloop
|
||||||
override fun shortDescription(): String = resourceHelper.gs(R.string.suspendloopforXmin, minutes.getMinutes())
|
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))
|
.add(LabelWithElement(injector, resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", minutes))
|
||||||
.build(root)
|
.build(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = minutes.value > 5
|
||||||
}
|
}
|
|
@ -59,4 +59,6 @@ class ActionNotification(injector: HasAndroidInjector) : Action(injector) {
|
||||||
.add(LabelWithElement(injector, resourceHelper.gs(R.string.message_short), "", text))
|
.add(LabelWithElement(injector, resourceHelper.gs(R.string.message_short), "", text))
|
||||||
.build(root)
|
.build(root)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = text.value.isNotEmpty()
|
||||||
}
|
}
|
|
@ -78,4 +78,6 @@ class ActionProfileSwitch(injector: HasAndroidInjector) : Action(injector) {
|
||||||
inputProfileName.value = JsonHelper.safeGetString(o, "profileToSwitchTo", "")
|
inputProfileName.value = JsonHelper.safeGetString(o, "profileToSwitchTo", "")
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = activePlugin.activeProfileInterface.profile?.getSpecificProfile(inputProfileName.value) != null
|
||||||
}
|
}
|
|
@ -23,7 +23,7 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector
|
||||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||||
|
|
||||||
var pct = InputPercent(injector)
|
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 friendlyName(): Int = R.string.profilepercentage
|
||||||
override fun shortDescription(): String =
|
override fun shortDescription(): String =
|
||||||
|
@ -66,4 +66,9 @@ class ActionProfileSwitchPercent(injector: HasAndroidInjector) : Action(injector
|
||||||
duration.value = JsonHelper.safeGetInt(o, "durationInMinutes")
|
duration.value = JsonHelper.safeGetInt(o, "durationInMinutes")
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean =
|
||||||
|
pct.value >= InputPercent.MIN &&
|
||||||
|
pct.value <= InputPercent.MAX &&
|
||||||
|
duration.value > 0
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@ import org.json.JSONObject
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) {
|
class ActionSendSMS(injector: HasAndroidInjector) : Action(injector) {
|
||||||
|
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
|
@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()
|
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 {
|
override fun toJSON(): String {
|
||||||
val data = JSONObject().put("text", text.value)
|
val data = JSONObject().put("text", text.value)
|
||||||
return JSONObject()
|
return JSONObject()
|
||||||
|
|
|
@ -25,11 +25,12 @@ import org.json.JSONObject
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
|
class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
|
||||||
|
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||||
|
|
||||||
var value = InputTempTarget(injector)
|
var value = InputTempTarget(injector)
|
||||||
var duration = InputDuration(injector, 0, InputDuration.TimeUnit.MINUTES)
|
var duration = InputDuration(injector, 30, InputDuration.TimeUnit.MINUTES)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
precondition = TriggerTempTarget(injector, ComparatorExists.Compare.NOT_EXISTS)
|
precondition = TriggerTempTarget(injector, ComparatorExists.Compare.NOT_EXISTS)
|
||||||
|
@ -83,4 +84,15 @@ class ActionStartTempTarget(injector: HasAndroidInjector) : Action(injector) {
|
||||||
.source(Source.USER)
|
.source(Source.USER)
|
||||||
.low(Profile.toMgdl(value.value, value.units))
|
.low(Profile.toMgdl(value.value, value.units))
|
||||||
.high(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
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -12,6 +12,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class ActionStopTempTarget(injector: HasAndroidInjector) : Action(injector) {
|
class ActionStopTempTarget(injector: HasAndroidInjector) : Action(injector) {
|
||||||
|
|
||||||
@Inject lateinit var resourceHelper: ResourceHelper
|
@Inject lateinit var resourceHelper: ResourceHelper
|
||||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||||
|
|
||||||
|
@ -29,4 +30,6 @@ class ActionStopTempTarget(injector: HasAndroidInjector) : Action(injector) {
|
||||||
activePlugin.activeTreatments.addToHistoryTempTarget(tempTarget)
|
activePlugin.activeTreatments.addToHistoryTempTarget(tempTarget)
|
||||||
callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run()
|
callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = true
|
||||||
}
|
}
|
|
@ -24,12 +24,11 @@ class InputDuration(injector: HasAndroidInjector) : Element(injector) {
|
||||||
val numberPicker : NumberPicker
|
val numberPicker : NumberPicker
|
||||||
if (unit == TimeUnit.MINUTES) {
|
if (unit == TimeUnit.MINUTES) {
|
||||||
numberPicker = MinutesNumberPicker(root.context, null)
|
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 {
|
} else {
|
||||||
numberPicker = NumberPicker(root.context, null)
|
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() }
|
numberPicker.setOnValueChangedListener { value: Double -> this.value = value.toInt() }
|
||||||
root.addView(numberPicker)
|
root.addView(numberPicker)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
|
|
||||||
class TriggerBolusAgo(injector: HasAndroidInjector) : Trigger(injector) {
|
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)
|
var comparator: Comparator = Comparator(injector)
|
||||||
|
|
||||||
private constructor(injector: HasAndroidInjector, triggerBolusAgo: TriggerBolusAgo) : this(injector) {
|
private constructor(injector: HasAndroidInjector, triggerBolusAgo: TriggerBolusAgo) : this(injector) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue