Triggers injection
This commit is contained in:
parent
bd1b1d8d76
commit
925de127a7
90 changed files with 2778 additions and 4284 deletions
|
@ -4,11 +4,15 @@ import dagger.BindsInstance
|
|||
import dagger.Component
|
||||
import dagger.android.AndroidInjectionModule
|
||||
import dagger.android.AndroidInjector
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.db.BgReading
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSMA.LoggerCallback
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.*
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
||||
import info.nightscout.androidaps.plugins.treatments.Treatment
|
||||
import info.nightscout.androidaps.queue.commands.CommandSetProfile
|
||||
|
@ -38,6 +42,26 @@ interface AppComponent : AndroidInjector<MainApp> {
|
|||
fun injectObjective5(objective5: Objective5)
|
||||
fun injectObjective6(objective6: Objective6)
|
||||
|
||||
fun injectAutomationEvent(automationEvent: AutomationEvent)
|
||||
|
||||
fun injectTrigger(trigger: Trigger)
|
||||
fun injectTrigger(triggerAutosensValue: TriggerAutosensValue)
|
||||
fun injectTrigger(triggerBg: TriggerBg)
|
||||
fun injectTrigger(triggerBolusAgo: TriggerBolusAgo)
|
||||
fun injectTrigger(triggerCOB: TriggerCOB)
|
||||
fun injectTrigger(triggerConnector: TriggerConnector)
|
||||
fun injectTrigger(triggerDelta: TriggerDelta)
|
||||
fun injectTrigger(triggerDummy: TriggerDummy)
|
||||
fun injectTrigger(triggerIob: TriggerIob)
|
||||
fun injectTrigger(triggerLocation: TriggerLocation)
|
||||
fun injectTrigger(triggerProfilePercent: TriggerProfilePercent)
|
||||
fun injectTrigger(triggerPumpLastConnection: TriggerPumpLastConnection)
|
||||
fun injectTrigger(triggerRecurringTime: TriggerRecurringTime)
|
||||
fun injectTrigger(triggerTempTarget: TriggerTempTarget)
|
||||
fun injectTrigger(triggerTime: TriggerTime)
|
||||
fun injectTrigger(triggerTimeRange : TriggerTimeRange)
|
||||
fun injectTrigger(triggerWifiSsid: TriggerWifiSsid)
|
||||
|
||||
fun injectAction(action: Action)
|
||||
fun injectActionDummy(action: ActionDummy)
|
||||
fun injectActionLoopDisable(action: ActionLoopDisable)
|
||||
|
@ -51,6 +75,23 @@ interface AppComponent : AndroidInjector<MainApp> {
|
|||
fun injectActionStartTempTarget(action: ActionStartTempTarget)
|
||||
fun injectActionStopTempTarget(action: ActionStopTempTarget)
|
||||
|
||||
fun injectElement(element: Element)
|
||||
fun injectElement(comparator: Comparator)
|
||||
fun injectElement(comparatorExists: ComparatorExists)
|
||||
fun injectElement(inputBg: InputBg)
|
||||
fun injectElement(inputButton: InputButton)
|
||||
fun injectElement(inputDelta: InputDelta)
|
||||
fun injectElement(inputDouble: InputDouble)
|
||||
fun injectElement(inputDuration: InputDuration)
|
||||
fun injectElement(inputInsulin: InputInsulin)
|
||||
fun injectElement(inputLocationMode: InputLocationMode)
|
||||
fun injectElement(inputPercent: InputPercent)
|
||||
fun injectElement(inputProfileName: InputProfileName)
|
||||
fun injectElement(inputString: InputString)
|
||||
fun injectElement(inputTempTarget: InputTempTarget)
|
||||
fun injectElement(labelWithElement: LabelWithElement)
|
||||
fun injectElement(staticLabel: StaticLabel)
|
||||
|
||||
fun injectTreatment(treatment: Treatment)
|
||||
fun injectBgReading(bgReading: BgReading)
|
||||
|
||||
|
|
|
@ -17,7 +17,10 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
|||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
|
||||
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.*
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.*
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
|
||||
import info.nightscout.androidaps.plugins.treatments.Treatment
|
||||
import info.nightscout.androidaps.queue.commands.CommandSetProfile
|
||||
|
@ -71,10 +74,30 @@ open class AppModule {
|
|||
@ContributesAndroidInjector fun objective5Injector(): Objective5
|
||||
@ContributesAndroidInjector fun objective6Injector(): Objective6
|
||||
|
||||
@ContributesAndroidInjector fun automationEventInjector(): AutomationEvent
|
||||
|
||||
@ContributesAndroidInjector fun triggerInjector(): Trigger
|
||||
@ContributesAndroidInjector fun triggerAutosensValueInjector(): TriggerAutosensValue
|
||||
@ContributesAndroidInjector fun triggerBgInjector(): TriggerBg
|
||||
@ContributesAndroidInjector fun triggerBolusAgoInjector(): TriggerBolusAgo
|
||||
@ContributesAndroidInjector fun triggerCOBInjector(): TriggerCOB
|
||||
@ContributesAndroidInjector fun triggerConnectorInjector(): TriggerConnector
|
||||
@ContributesAndroidInjector fun triggerDeltaInjector(): TriggerDelta
|
||||
@ContributesAndroidInjector fun triggerDummyInjector(): TriggerDummy
|
||||
@ContributesAndroidInjector fun triggerIobInjector(): TriggerIob
|
||||
@ContributesAndroidInjector fun triggerLocationInjector(): TriggerLocation
|
||||
@ContributesAndroidInjector fun triggerProfilePercentInjector(): TriggerProfilePercent
|
||||
@ContributesAndroidInjector fun triggerPumpLastConnectonInjector(): TriggerPumpLastConnection
|
||||
@ContributesAndroidInjector fun triggerRecurringTimeInjector(): TriggerRecurringTime
|
||||
@ContributesAndroidInjector fun triggerTempTargetInjector(): TriggerTempTarget
|
||||
@ContributesAndroidInjector fun triggerTime(): TriggerTime
|
||||
@ContributesAndroidInjector fun triggerTimeRangeInjector(): TriggerTimeRange
|
||||
@ContributesAndroidInjector fun triggerWifiSsidInjector(): TriggerWifiSsid
|
||||
|
||||
@ContributesAndroidInjector fun actionInjector(): Action
|
||||
@ContributesAndroidInjector fun actionLoopDisableInjector(): ActionLoopDisable
|
||||
@ContributesAndroidInjector fun actionLoopEnableInjector(): ActionLoopEnable
|
||||
@ContributesAndroidInjector fun ActionLoopResumeInjector(): ActionLoopResume
|
||||
@ContributesAndroidInjector fun actionLoopResumeInjector(): ActionLoopResume
|
||||
@ContributesAndroidInjector fun actionLoopSuspendInjector(): ActionLoopSuspend
|
||||
@ContributesAndroidInjector fun actionNotificationInjector(): ActionNotification
|
||||
@ContributesAndroidInjector fun actionProfileSwitchInjector(): ActionProfileSwitch
|
||||
|
@ -84,6 +107,23 @@ open class AppModule {
|
|||
@ContributesAndroidInjector fun actionStopTempTargetInjector(): ActionStopTempTarget
|
||||
@ContributesAndroidInjector fun actionDummyInjector(): ActionDummy
|
||||
|
||||
@ContributesAndroidInjector fun elementInjector(): Element
|
||||
@ContributesAndroidInjector fun comparatorInjector(): Comparator
|
||||
@ContributesAndroidInjector fun comparatorExistsInjector(): ComparatorExists
|
||||
@ContributesAndroidInjector fun inputBgInjector(): InputBg
|
||||
@ContributesAndroidInjector fun inputButtonInjector(): InputButton
|
||||
@ContributesAndroidInjector fun inputDeltaInjector(): InputDelta
|
||||
@ContributesAndroidInjector fun inputDoubleInjector(): InputDouble
|
||||
@ContributesAndroidInjector fun inputDurationInjector(): InputDuration
|
||||
@ContributesAndroidInjector fun inputInsulinInjector(): InputInsulin
|
||||
@ContributesAndroidInjector fun inputLocationModeInjector(): InputLocationMode
|
||||
@ContributesAndroidInjector fun inputPercentInjector(): InputPercent
|
||||
@ContributesAndroidInjector fun inputProfileNameInjector(): InputProfileName
|
||||
@ContributesAndroidInjector fun inputStringInjector(): InputString
|
||||
@ContributesAndroidInjector fun inputTempTargetInjector(): InputTempTarget
|
||||
@ContributesAndroidInjector fun labelWithElementInjector(): LabelWithElement
|
||||
@ContributesAndroidInjector fun staticLabelInjector(): StaticLabel
|
||||
|
||||
@ContributesAndroidInjector fun bgReadingInjector(): BgReading
|
||||
@ContributesAndroidInjector fun treatmentInjector(): Treatment
|
||||
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionDummy;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AutomationEvent {
|
||||
private static final Logger log = LoggerFactory.getLogger(AutomationEvent.class);
|
||||
|
||||
private Trigger trigger = new TriggerConnector();
|
||||
private List<Action> actions = new ArrayList<>();
|
||||
private String title;
|
||||
private boolean enabled = true;
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public void setTrigger(Trigger trigger) {
|
||||
this.trigger = trigger;
|
||||
}
|
||||
|
||||
public Trigger getTrigger() {
|
||||
return trigger;
|
||||
}
|
||||
|
||||
public List<Action> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean newState) {
|
||||
enabled = newState;
|
||||
}
|
||||
|
||||
public TriggerConnector getPreconditions() {
|
||||
TriggerConnector trigger = new TriggerConnector(TriggerConnector.Type.AND);
|
||||
for (Action action : actions) {
|
||||
if (action.getPrecondition() != null)
|
||||
trigger.add(action.getPrecondition());
|
||||
}
|
||||
return trigger;
|
||||
}
|
||||
|
||||
public void addAction(Action action) {
|
||||
actions.add(action);
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
// title
|
||||
o.put("title", title);
|
||||
o.put("enabled", enabled);
|
||||
// trigger
|
||||
o.put("trigger", trigger.toJSON());
|
||||
// actions
|
||||
JSONArray array = new JSONArray();
|
||||
for (Action a : actions) {
|
||||
array.put(a.toJSON());
|
||||
}
|
||||
o.put("actions", array);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
public AutomationEvent fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
title = d.optString("title", "");
|
||||
enabled = d.optBoolean("enabled", true);
|
||||
trigger = Trigger.instantiate(d.getString("trigger"));
|
||||
JSONArray array = d.getJSONArray("actions");
|
||||
actions.clear();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
actions.add(new ActionDummy(MainApp.instance()).instantiate(new JSONObject(array.getString(i))));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation
|
||||
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionDummy
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDummy
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
||||
class AutomationEvent(private val mainApp: MainApp) {
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
|
||||
var trigger: Trigger = TriggerConnector(mainApp)
|
||||
val actions: MutableList<Action> = ArrayList()
|
||||
var title: String? = null
|
||||
var isEnabled = true
|
||||
var lastRun: Long = 0
|
||||
|
||||
init {
|
||||
mainApp.androidInjector().inject(this)
|
||||
}
|
||||
|
||||
fun getPreconditions(): TriggerConnector {
|
||||
val trigger = TriggerConnector(mainApp, TriggerConnector.Type.AND)
|
||||
for (action in actions) {
|
||||
action.precondition?.let { trigger.add(it) }
|
||||
}
|
||||
return trigger
|
||||
}
|
||||
|
||||
fun addAction(action: Action) = actions.add(action)
|
||||
|
||||
fun toJSON(): String {
|
||||
val array = JSONArray()
|
||||
for (a in actions) array.put(a.toJSON())
|
||||
return JSONObject()
|
||||
.put("title", title)
|
||||
.put("enabled", isEnabled)
|
||||
.put("trigger", trigger.toJSON())
|
||||
.put("actions", array)
|
||||
.toString()
|
||||
}
|
||||
|
||||
fun fromJSON(data: String?): AutomationEvent {
|
||||
val d = JSONObject(data)
|
||||
title = d.optString("title", "")
|
||||
isEnabled = d.optBoolean("enabled", true)
|
||||
trigger = TriggerDummy(mainApp).instantiate(JSONObject(d.getString("trigger")))
|
||||
?: TriggerConnector(mainApp)
|
||||
val array = d.getJSONArray("actions")
|
||||
actions.clear()
|
||||
for (i in 0 until array.length()) {
|
||||
ActionDummy(mainApp).instantiate(JSONObject(array.getString(i)))?.let {
|
||||
actions.add(it)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
fun shouldRun() : Boolean{
|
||||
return lastRun <= DateUtil.now() - T.mins(5).msecs()
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ import androidx.recyclerview.widget.ItemTouchHelper
|
|||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog
|
||||
|
@ -45,6 +46,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var automationPlugin: AutomationPlugin
|
||||
@Inject lateinit var mainApp : MainApp
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
private lateinit var eventListAdapter: EventListAdapter
|
||||
|
@ -67,7 +69,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
automation_fabAddEvent.setOnClickListener {
|
||||
val dialog = EditEventDialog()
|
||||
val args = Bundle()
|
||||
args.putString("event", AutomationEvent().toJSON())
|
||||
args.putString("event", AutomationEvent(mainApp).toJSON())
|
||||
args.putInt("position", -1) // New event
|
||||
dialog.arguments = args
|
||||
fragmentManager?.let { dialog.show(it, "EditEventDialog") }
|
||||
|
@ -116,6 +118,19 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
itemTouchHelper?.startDrag(viewHolder)
|
||||
}
|
||||
|
||||
fun fillIconSet(connector: TriggerConnector, set: HashSet<Int>) {
|
||||
for (t in connector.list) {
|
||||
if (t is TriggerConnector) {
|
||||
fillIconSet(t, set)
|
||||
} else {
|
||||
val icon = t.icon()
|
||||
if (icon.isPresent) {
|
||||
set.add(icon.get()!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inner class EventListAdapter : RecyclerView.Adapter<EventListAdapter.ViewHolder>(), ItemTouchHelperAdapter {
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val v = LayoutInflater.from(parent.context).inflate(R.layout.automation_event_item, parent, false)
|
||||
|
@ -137,7 +152,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
holder.iconLayout.removeAllViews()
|
||||
// trigger icons
|
||||
val triggerIcons = HashSet<Int>()
|
||||
TriggerConnector.fillIconSet(event.trigger as TriggerConnector, triggerIcons)
|
||||
fillIconSet(event.trigger as TriggerConnector, triggerIcons)
|
||||
for (res in triggerIcons) {
|
||||
addImage(res, holder.context, holder.iconLayout)
|
||||
}
|
||||
|
|
|
@ -149,7 +149,7 @@ class AutomationPlugin @Inject constructor(
|
|||
val array = JSONArray(data)
|
||||
for (i in 0 until array.length()) {
|
||||
val o = array.getJSONObject(i)
|
||||
val event = AutomationEvent().fromJSON(o.toString())
|
||||
val event = AutomationEvent(mainApp).fromJSON(o.toString())
|
||||
automationEvents.add(event)
|
||||
}
|
||||
} catch (e: JSONException) {
|
||||
|
@ -169,7 +169,7 @@ class AutomationPlugin @Inject constructor(
|
|||
|
||||
aapsLogger.debug(LTag.AUTOMATION, "processActions")
|
||||
for (event in automationEvents) {
|
||||
if (event.isEnabled && event.trigger.shouldRun() && event.preconditions.shouldRun()) {
|
||||
if (event.isEnabled && event.shouldRun() && event.trigger.shouldRun() && event.getPreconditions().shouldRun()) {
|
||||
val actions = event.actions
|
||||
for (action in actions) {
|
||||
action.doAction(object : Callback() {
|
||||
|
@ -190,7 +190,7 @@ class AutomationPlugin @Inject constructor(
|
|||
}
|
||||
})
|
||||
}
|
||||
event.trigger.executed(DateUtil.now())
|
||||
event.lastRun = DateUtil.now()
|
||||
}
|
||||
}
|
||||
storeToSP() // save last run time
|
||||
|
@ -213,20 +213,20 @@ class AutomationPlugin @Inject constructor(
|
|||
|
||||
fun getTriggerDummyObjects(): List<Trigger> {
|
||||
return listOf(
|
||||
TriggerTime(),
|
||||
TriggerRecurringTime(),
|
||||
TriggerTimeRange(),
|
||||
TriggerBg(),
|
||||
TriggerDelta(),
|
||||
TriggerIob(),
|
||||
TriggerCOB(),
|
||||
TriggerProfilePercent(),
|
||||
TriggerTempTarget(),
|
||||
TriggerWifiSsid(),
|
||||
TriggerLocation(),
|
||||
TriggerAutosensValue(),
|
||||
TriggerBolusAgo(),
|
||||
TriggerPumpLastConnection()
|
||||
TriggerTime(mainApp),
|
||||
TriggerRecurringTime(mainApp),
|
||||
TriggerTimeRange(mainApp),
|
||||
TriggerBg(mainApp),
|
||||
TriggerDelta(mainApp),
|
||||
TriggerIob(mainApp),
|
||||
TriggerCOB(mainApp),
|
||||
TriggerProfilePercent(mainApp),
|
||||
TriggerTempTarget(mainApp),
|
||||
TriggerWifiSsid(mainApp),
|
||||
TriggerLocation(mainApp),
|
||||
TriggerAutosensValue(mainApp),
|
||||
TriggerBolusAgo(mainApp),
|
||||
TriggerPumpLastConnection(mainApp)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP
|
|||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
abstract class Action(val mainApp: MainApp) {
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
|
@ -61,7 +62,7 @@ abstract class Action(val mainApp: MainApp) {
|
|||
val type = obj.getString("type")
|
||||
val data = obj.optJSONObject("data")
|
||||
val clazz = Class.forName(type).kotlin
|
||||
return (clazz.constructors.first().call(mainApp) as Action).fromJSON(data?.toString()
|
||||
return (clazz.primaryConstructor?.call(mainApp) as Action).fromJSON(data?.toString()
|
||||
?: "")
|
||||
//return (clazz.newInstance() as Action).fromJSON(data?.toString() ?: "")
|
||||
} catch (e: ClassNotFoundException) {
|
||||
|
|
|
@ -14,15 +14,15 @@ import info.nightscout.androidaps.utils.JsonHelper
|
|||
import org.json.JSONObject
|
||||
|
||||
class ActionLoopSuspend(mainApp: MainApp) : Action(mainApp) {
|
||||
var minutes = InputDuration(0, InputDuration.TimeUnit.MINUTES)
|
||||
var minutes = InputDuration(mainApp, 0, InputDuration.TimeUnit.MINUTES)
|
||||
|
||||
override fun friendlyName(): Int = R.string.suspendloop
|
||||
override fun shortDescription(): String = resourceHelper.gs(R.string.suspendloopforXmin, minutes.minutes)
|
||||
override fun shortDescription(): String = resourceHelper.gs(R.string.suspendloopforXmin, minutes.getMinutes())
|
||||
@DrawableRes override fun icon(): Int = R.drawable.ic_pause_circle_outline_24dp
|
||||
|
||||
override fun doAction(callback: Callback) {
|
||||
if (!loopPlugin.isSuspended) {
|
||||
loopPlugin.suspendLoop(minutes.minutes)
|
||||
loopPlugin.suspendLoop(minutes.getMinutes())
|
||||
rxBus.send(EventRefreshOverview("ActionLoopSuspend"))
|
||||
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
|
||||
} else {
|
||||
|
@ -31,7 +31,7 @@ class ActionLoopSuspend(mainApp: MainApp) : Action(mainApp) {
|
|||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject().put("minutes", minutes.minutes)
|
||||
val data = JSONObject().put("minutes", minutes.getMinutes())
|
||||
return JSONObject()
|
||||
.put("type", this.javaClass.name)
|
||||
.put("data", data)
|
||||
|
@ -40,7 +40,7 @@ class ActionLoopSuspend(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun fromJSON(data: String): Action {
|
||||
val o = JSONObject(data)
|
||||
minutes.minutes = JsonHelper.safeGetInt(o, "minutes")
|
||||
minutes.setMinutes(JsonHelper.safeGetInt(o, "minutes"))
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class ActionLoopSuspend(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", minutes))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", minutes))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ import info.nightscout.androidaps.utils.JsonHelper
|
|||
import org.json.JSONObject
|
||||
|
||||
class ActionNotification(mainApp: MainApp) : Action(mainApp) {
|
||||
var text = InputString()
|
||||
var text = InputString(mainApp)
|
||||
|
||||
override fun friendlyName(): Int = R.string.notification
|
||||
override fun shortDescription(): String = resourceHelper.gs(R.string.notification_message, text.value)
|
||||
|
@ -41,7 +41,7 @@ class ActionNotification(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun fromJSON(data: String): Action {
|
||||
val o = JSONObject(data)
|
||||
text.value = JsonHelper.safeGetString(o, "text")
|
||||
text.value = JsonHelper.safeGetString(o, "text", "")
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ class ActionNotification(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.message_short), "", text))
|
||||
.add(LabelWithElement(mainApp,resourceHelper.gs(R.string.message_short), "", text))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ import info.nightscout.androidaps.utils.JsonHelper
|
|||
import org.json.JSONObject
|
||||
|
||||
class ActionProfileSwitch(mainApp: MainApp) : Action(mainApp) {
|
||||
var inputProfileName: InputProfileName = InputProfileName("")
|
||||
var inputProfileName: InputProfileName = InputProfileName(mainApp, "")
|
||||
|
||||
override fun friendlyName(): Int = R.string.profilename
|
||||
override fun shortDescription(): String = resourceHelper.gs(R.string.changengetoprofilename, inputProfileName.value)
|
||||
|
@ -51,7 +51,7 @@ class ActionProfileSwitch(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.profilename), "", inputProfileName))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.profilename), "", inputProfileName))
|
||||
.build(root)
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ class ActionProfileSwitch(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun fromJSON(data: String): Action {
|
||||
val o = JSONObject(data)
|
||||
inputProfileName.value = JsonHelper.safeGetString(o, "profileToSwitchTo")
|
||||
inputProfileName.value = JsonHelper.safeGetString(o, "profileToSwitchTo", "")
|
||||
return this
|
||||
}
|
||||
}
|
|
@ -16,29 +16,29 @@ import info.nightscout.androidaps.utils.JsonHelper
|
|||
import org.json.JSONObject
|
||||
|
||||
class ActionProfileSwitchPercent(mainApp: MainApp) : Action(mainApp) {
|
||||
var pct = InputPercent()
|
||||
var duration = InputDuration(0, InputDuration.TimeUnit.MINUTES)
|
||||
var pct = InputPercent(mainApp)
|
||||
var duration = InputDuration(mainApp, 0, InputDuration.TimeUnit.MINUTES)
|
||||
|
||||
override fun friendlyName(): Int = R.string.profilepercentage
|
||||
override fun shortDescription(): String =
|
||||
if (duration.minutes == 0) resourceHelper.gs(R.string.startprofileforever, pct.value.toInt())
|
||||
else resourceHelper.gs(R.string.startprofile, pct.value.toInt(), duration.minutes)
|
||||
if (duration.value == 0) resourceHelper.gs(R.string.startprofileforever, pct.value.toInt())
|
||||
else resourceHelper.gs(R.string.startprofile, pct.value.toInt(), duration.value)
|
||||
|
||||
@DrawableRes override fun icon(): Int = R.drawable.icon_actions_profileswitch
|
||||
|
||||
init {
|
||||
precondition = TriggerProfilePercent().comparator(Comparator.Compare.IS_EQUAL).setValue(100.0)
|
||||
precondition = TriggerProfilePercent(mainApp, 100.0, Comparator.Compare.IS_EQUAL)
|
||||
}
|
||||
|
||||
override fun doAction(callback: Callback) {
|
||||
treatmentsPlugin.doProfileSwitch(duration.value.toInt(), pct.value.toInt(), 0)
|
||||
treatmentsPlugin.doProfileSwitch(duration.value, pct.value.toInt(), 0)
|
||||
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
|
||||
}
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.percent_u), "", pct))
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.percent_u), "", pct))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
|
||||
.build(root)
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ class ActionProfileSwitchPercent(mainApp: MainApp) : Action(mainApp) {
|
|||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("percentage", pct.value)
|
||||
.put("durationInMinutes", duration.minutes)
|
||||
.put("durationInMinutes", duration.value)
|
||||
return JSONObject()
|
||||
.put("type", this.javaClass.name)
|
||||
.put("data", data)
|
||||
|
@ -57,7 +57,7 @@ class ActionProfileSwitchPercent(mainApp: MainApp) : Action(mainApp) {
|
|||
override fun fromJSON(data: String): Action {
|
||||
val o = JSONObject(data)
|
||||
pct.value = JsonHelper.safeGetDouble(o, "percentage")
|
||||
duration.minutes = JsonHelper.safeGetInt(o, "durationInMinutes")
|
||||
duration.value = JsonHelper.safeGetInt(o, "durationInMinutes")
|
||||
return this
|
||||
}
|
||||
}
|
|
@ -8,11 +8,11 @@ import info.nightscout.androidaps.plugins.general.automation.elements.InputStrin
|
|||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import org.json.JSONObject
|
||||
|
||||
class ActionSendSMS(mainApp: MainApp) : Action(mainApp) {
|
||||
var text = InputString()
|
||||
var text = InputString(mainApp)
|
||||
|
||||
override fun friendlyName(): Int = R.string.sendsmsactiondescription
|
||||
override fun shortDescription(): String = resourceHelper.gs(R.string.sendsmsactionlabel, text.value)
|
||||
|
@ -33,7 +33,7 @@ class ActionSendSMS(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun fromJSON(data: String): Action {
|
||||
val o = JSONObject(data)
|
||||
text.value = safeGetString(o, "text")
|
||||
text.value = JsonHelper.safeGetString(o, "text", "")
|
||||
return this
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ class ActionSendSMS(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.sendsmsactiontext), "", text))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.sendsmsactiontext), "", text))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -17,17 +17,16 @@ import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuil
|
|||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTempTarget
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetDouble
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||
import org.json.JSONObject
|
||||
|
||||
class ActionStartTempTarget(mainApp: MainApp) : Action(mainApp) {
|
||||
var value = InputTempTarget()
|
||||
var duration = InputDuration(0, InputDuration.TimeUnit.MINUTES)
|
||||
var value = InputTempTarget(mainApp)
|
||||
var duration = InputDuration(mainApp, 0, InputDuration.TimeUnit.MINUTES)
|
||||
|
||||
init {
|
||||
precondition = TriggerTempTarget().comparator(ComparatorExists.Compare.NOT_EXISTS)
|
||||
precondition = TriggerTempTarget(mainApp, ComparatorExists.Compare.NOT_EXISTS)
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.starttemptarget
|
||||
|
@ -42,8 +41,8 @@ class ActionStartTempTarget(mainApp: MainApp) : Action(mainApp) {
|
|||
override fun generateDialog(root: LinearLayout) {
|
||||
val unitResId = if (value.units == Constants.MGDL) R.string.mgdl else R.string.mmol
|
||||
LayoutBuilder()
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.careportal_temporarytarget) + "\n[" + resourceHelper.gs(unitResId) + "]", "", value))
|
||||
.add(LabelWithElement(resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.careportal_temporarytarget) + "\n[" + resourceHelper.gs(unitResId) + "]", "", value))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
|
||||
.build(root)
|
||||
}
|
||||
|
||||
|
@ -55,7 +54,7 @@ class ActionStartTempTarget(mainApp: MainApp) : Action(mainApp) {
|
|||
val data = JSONObject()
|
||||
.put("value", value.value)
|
||||
.put("units", value.units)
|
||||
.put("durationInMinutes", duration.minutes)
|
||||
.put("durationInMinutes", duration.getMinutes())
|
||||
return JSONObject()
|
||||
.put("type", this.javaClass.name)
|
||||
.put("data", data)
|
||||
|
@ -64,16 +63,16 @@ class ActionStartTempTarget(mainApp: MainApp) : Action(mainApp) {
|
|||
|
||||
override fun fromJSON(data: String): Action {
|
||||
val o = JSONObject(data)
|
||||
value.units = safeGetString(o, "units")
|
||||
value.units = JsonHelper.safeGetString(o, "units", Constants.MGDL)
|
||||
value.value = safeGetDouble(o, "value")
|
||||
duration.minutes = safeGetInt(o, "durationInMinutes")
|
||||
duration.setMinutes(JsonHelper.safeGetInt(o, "durationInMinutes"))
|
||||
return this
|
||||
}
|
||||
|
||||
fun tt(): TempTarget =
|
||||
TempTarget()
|
||||
.date(DateUtil.now())
|
||||
.duration(duration.minutes)
|
||||
.duration(duration.getMinutes())
|
||||
.reason("Automation")
|
||||
.source(Source.USER)
|
||||
.low(Profile.toMgdl(value.value, value.units))
|
||||
|
|
|
@ -15,6 +15,7 @@ import info.nightscout.androidaps.plugins.general.automation.events.EventAutomat
|
|||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
|
||||
import kotlinx.android.synthetic.main.automation_dialog_choose_action.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
class ChooseActionDialog : DialogFragmentWithDate() {
|
||||
@Inject lateinit var automationPlugin: AutomationPlugin
|
||||
|
@ -64,7 +65,7 @@ class ChooseActionDialog : DialogFragmentWithDate() {
|
|||
private fun instantiateAction(): Action? {
|
||||
return getActionClass()?.let {
|
||||
val clazz = Class.forName(it).kotlin
|
||||
clazz.constructors.first().call(mainApp) as Action
|
||||
clazz.primaryConstructor?.call(mainApp) as Action
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,18 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.RadioButton
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
|
||||
import kotlinx.android.synthetic.main.automation_dialog_choose_trigger.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
class ChooseTriggerDialog : DialogFragmentWithDate() {
|
||||
@Inject lateinit var automationPlugin: AutomationPlugin
|
||||
@Inject lateinit var mainApp : MainApp
|
||||
|
||||
private var checkedIndex = -1
|
||||
private var clickListener: OnClickListener? = null
|
||||
|
@ -39,7 +42,7 @@ class ChooseTriggerDialog : DialogFragmentWithDate() {
|
|||
for (t in automationPlugin.getTriggerDummyObjects()) {
|
||||
val radioButton = RadioButton(context)
|
||||
radioButton.setText(t.friendlyName())
|
||||
radioButton.tag = t.javaClass
|
||||
radioButton.tag = t.javaClass.name
|
||||
automation_chooseTriggerRadioGroup.addView(radioButton)
|
||||
}
|
||||
|
||||
|
@ -65,15 +68,16 @@ class ChooseTriggerDialog : DialogFragmentWithDate() {
|
|||
|
||||
private fun instantiateTrigger(): Trigger? {
|
||||
return getTriggerClass()?.let {
|
||||
it.newInstance() as Trigger
|
||||
val clazz = Class.forName(it).kotlin
|
||||
clazz.primaryConstructor?.call(mainApp) as Trigger
|
||||
}
|
||||
}
|
||||
|
||||
private fun getTriggerClass(): Class<*>? {
|
||||
private fun getTriggerClass(): String? {
|
||||
val radioButtonID = automation_chooseTriggerRadioGroup.checkedRadioButtonId
|
||||
val radioButton = automation_chooseTriggerRadioGroup.findViewById<RadioButton>(radioButtonID)
|
||||
return radioButton?.let {
|
||||
it.tag as Class<*>
|
||||
it.tag as String
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.widget.LinearLayout
|
|||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
|
@ -31,21 +32,23 @@ import javax.inject.Inject
|
|||
|
||||
class EditEventDialog : DialogFragmentWithDate() {
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var mainApp: MainApp
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var automationPlugin: AutomationPlugin
|
||||
|
||||
private var actionListAdapter: ActionListAdapter? = null
|
||||
private var event: AutomationEvent = AutomationEvent()
|
||||
private lateinit var event: AutomationEvent
|
||||
private var position: Int = -1
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
event = AutomationEvent(mainApp)
|
||||
// load data from bundle
|
||||
(savedInstanceState ?: arguments)?.let { bundle ->
|
||||
position = bundle.getInt("position", -1)
|
||||
bundle.getString("event")?.let { event = AutomationEvent().fromJSON(it) }
|
||||
bundle.getString("event")?.let { event = AutomationEvent(mainApp).fromJSON(it) }
|
||||
}
|
||||
|
||||
onCreateViewGeneral()
|
||||
|
@ -149,7 +152,7 @@ class EditEventDialog : DialogFragmentWithDate() {
|
|||
}
|
||||
|
||||
private fun showPreconditions() {
|
||||
val forcedTriggers = event.preconditions
|
||||
val forcedTriggers = event.getPreconditions()
|
||||
if (forcedTriggers.size() > 0) {
|
||||
automation_forcedTriggerDescription.visibility = View.VISIBLE
|
||||
automation_forcedTriggerDescriptionLabel.visibility = View.VISIBLE
|
||||
|
|
|
@ -4,16 +4,20 @@ import android.os.Bundle
|
|||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDummy
|
||||
import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.*
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
|
||||
class EditTriggerDialog : DialogFragmentWithDate() {
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var mainApp: MainApp
|
||||
|
||||
private var trigger: Trigger? = null
|
||||
|
||||
|
@ -21,7 +25,7 @@ class EditTriggerDialog : DialogFragmentWithDate() {
|
|||
savedInstanceState: Bundle?): View? {
|
||||
// load data from bundle
|
||||
(savedInstanceState ?: arguments)?.let { bundle ->
|
||||
bundle.getString("trigger")?.let { trigger = Trigger.instantiate(it) }
|
||||
bundle.getString("trigger")?.let { trigger = TriggerDummy(mainApp).instantiate(JSONObject(it)) }
|
||||
}
|
||||
|
||||
onCreateViewGeneral()
|
||||
|
@ -32,7 +36,7 @@ class EditTriggerDialog : DialogFragmentWithDate() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
// display root trigger
|
||||
trigger?.generateDialog(automation_layoutTrigger, fragmentManager)
|
||||
trigger?.generateDialog(automation_layoutTrigger)
|
||||
}
|
||||
|
||||
override fun submit(): Boolean {
|
||||
|
|
|
@ -15,29 +15,28 @@ import info.nightscout.androidaps.MainApp;
|
|||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
|
||||
public class TriggerListAdapter {
|
||||
private final LinearLayout mRootLayout;
|
||||
private final FragmentManager mFragmentManager;
|
||||
private final Context mContext;
|
||||
private final TriggerConnector mRootConnector;
|
||||
private final MainApp mainApp;
|
||||
private final ResourceHelper resourceHelper;
|
||||
|
||||
public TriggerListAdapter(FragmentManager fragmentManager, Context context, LinearLayout rootLayout, TriggerConnector rootTrigger) {
|
||||
public TriggerListAdapter(MainApp mainApp, ResourceHelper resourceHelper, Context context, LinearLayout rootLayout, TriggerConnector rootTrigger) {
|
||||
mRootLayout = rootLayout;
|
||||
mFragmentManager = fragmentManager;
|
||||
this.mainApp = mainApp;
|
||||
this.resourceHelper = resourceHelper;
|
||||
mContext = context;
|
||||
mRootConnector = rootTrigger;
|
||||
build(fragmentManager);
|
||||
build(rootTrigger.scanForActivity(context).getSupportFragmentManager());
|
||||
}
|
||||
|
||||
public Context getContext() {
|
||||
return mContext;
|
||||
}
|
||||
|
||||
private FragmentManager getFM() {
|
||||
return mFragmentManager;
|
||||
}
|
||||
|
||||
private void destroy() {
|
||||
mRootLayout.removeAllViews();
|
||||
}
|
||||
|
@ -48,11 +47,11 @@ public class TriggerListAdapter {
|
|||
|
||||
// spinner
|
||||
if (i > 0) {
|
||||
createSpinner(trigger);
|
||||
createSpinner(trigger, fragmentManager);
|
||||
}
|
||||
|
||||
// trigger layout
|
||||
trigger.generateDialog(mRootLayout, fragmentManager);
|
||||
trigger.generateDialog(mRootLayout);
|
||||
|
||||
// buttons
|
||||
createButtons(fragmentManager, trigger);
|
||||
|
@ -60,7 +59,7 @@ public class TriggerListAdapter {
|
|||
|
||||
if (mRootConnector.size() == 0) {
|
||||
Button buttonAdd = new Button(mContext);
|
||||
buttonAdd.setText(MainApp.gs(R.string.addnew));
|
||||
buttonAdd.setText(resourceHelper.gs(R.string.addnew));
|
||||
buttonAdd.setOnClickListener(v -> {
|
||||
ChooseTriggerDialog dialog = new ChooseTriggerDialog();
|
||||
dialog.setOnClickListener(newTriggerObject -> {
|
||||
|
@ -75,30 +74,30 @@ public class TriggerListAdapter {
|
|||
|
||||
private Spinner createSpinner() {
|
||||
Spinner spinner = new Spinner(mContext);
|
||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(mContext, R.layout.spinner_centered, TriggerConnector.Type.labels());
|
||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(mContext, R.layout.spinner_centered, TriggerConnector.Type.AND.labels(resourceHelper));
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(spinnerArrayAdapter);
|
||||
return spinner;
|
||||
}
|
||||
|
||||
private void createSpinner(Trigger trigger) {
|
||||
private void createSpinner(Trigger trigger, FragmentManager fragmentManager) {
|
||||
final TriggerConnector connector = trigger.getConnector();
|
||||
final int initialPosition = connector.getConnectorType().ordinal();
|
||||
Spinner spinner = createSpinner();
|
||||
spinner.setSelection(initialPosition);
|
||||
spinner.setBackgroundColor(MainApp.gc(R.color.black_overlay));
|
||||
spinner.setBackgroundColor(resourceHelper.gc(R.color.black_overlay));
|
||||
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
params.setMargins(0, MainApp.dpToPx(8), 0, MainApp.dpToPx(8));
|
||||
params.setMargins(0, resourceHelper.dpToPx(8), 0, resourceHelper.dpToPx(8));
|
||||
spinner.setLayoutParams(params);
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
if (position != initialPosition) {
|
||||
// connector type changed
|
||||
changeConnector(getFM(), trigger, connector, TriggerConnector.Type.values()[position]);
|
||||
changeConnector(fragmentManager, trigger, connector, TriggerConnector.Type.values()[position]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,35 +122,35 @@ public class TriggerListAdapter {
|
|||
|
||||
// Button [-]
|
||||
Button buttonRemove = new Button(mContext);
|
||||
buttonRemove.setText(MainApp.gs(R.string.delete_short));
|
||||
buttonRemove.setText(resourceHelper.gs(R.string.delete_short));
|
||||
buttonRemove.setOnClickListener(v -> {
|
||||
final TriggerConnector connector = trigger.getConnector();
|
||||
connector.remove(trigger);
|
||||
connector.simplify().rebuildView(getFM());
|
||||
connector.simplify().rebuildView(fragmentManager);
|
||||
});
|
||||
buttonLayout.addView(buttonRemove);
|
||||
|
||||
// Button [+]
|
||||
Button buttonAdd = new Button(mContext);
|
||||
buttonAdd.setText(MainApp.gs(R.string.add_short));
|
||||
buttonAdd.setText(resourceHelper.gs(R.string.add_short));
|
||||
buttonAdd.setOnClickListener(v -> {
|
||||
ChooseTriggerDialog dialog = new ChooseTriggerDialog();
|
||||
dialog.show(fragmentManager, "ChooseTriggerDialog");
|
||||
dialog.setOnClickListener(newTriggerObject -> {
|
||||
TriggerConnector connector = trigger.getConnector();
|
||||
connector.add(connector.pos(trigger) + 1, newTriggerObject);
|
||||
connector.simplify().rebuildView(getFM());
|
||||
connector.simplify().rebuildView(fragmentManager);
|
||||
});
|
||||
});
|
||||
buttonLayout.addView(buttonAdd);
|
||||
|
||||
// Button [*]
|
||||
Button buttonCopy = new Button(mContext);
|
||||
buttonCopy.setText(MainApp.gs(R.string.copy_short));
|
||||
buttonCopy.setText(resourceHelper.gs(R.string.copy_short));
|
||||
buttonCopy.setOnClickListener(v -> {
|
||||
TriggerConnector connector = trigger.getConnector();
|
||||
connector.add(connector.pos(trigger) + 1, trigger.duplicate());
|
||||
connector.simplify().rebuildView(getFM());
|
||||
connector.simplify().rebuildView(fragmentManager);
|
||||
});
|
||||
buttonLayout.addView(buttonCopy);
|
||||
}
|
||||
|
@ -161,12 +160,12 @@ public class TriggerListAdapter {
|
|||
build(fragmentManager);
|
||||
}
|
||||
|
||||
public static void changeConnector(final FragmentManager fragmentManager, final Trigger trigger, final TriggerConnector connector, final TriggerConnector.Type newConnectorType) {
|
||||
public void changeConnector(final FragmentManager fragmentManager, final Trigger trigger, final TriggerConnector connector, final TriggerConnector.Type newConnectorType) {
|
||||
if (connector.size() > 2) {
|
||||
// split connector
|
||||
int pos = connector.pos(trigger) - 1;
|
||||
|
||||
TriggerConnector newConnector = new TriggerConnector(newConnectorType);
|
||||
TriggerConnector newConnector = new TriggerConnector(mainApp, newConnectorType);
|
||||
|
||||
// move trigger from pos and pos+1 into new connector
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
|
@ -177,10 +176,8 @@ public class TriggerListAdapter {
|
|||
|
||||
connector.add(pos, newConnector);
|
||||
} else {
|
||||
connector.changeConnectorType(newConnectorType);
|
||||
connector.setType(newConnectorType);
|
||||
}
|
||||
|
||||
connector.simplify().rebuildView(fragmentManager);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
public class Comparator extends Element {
|
||||
public enum Compare {
|
||||
IS_LESSER,
|
||||
IS_EQUAL_OR_LESSER,
|
||||
IS_EQUAL,
|
||||
IS_EQUAL_OR_GREATER,
|
||||
IS_GREATER,
|
||||
IS_NOT_AVAILABLE;
|
||||
|
||||
public @StringRes
|
||||
int getStringRes() {
|
||||
switch (this) {
|
||||
case IS_LESSER:
|
||||
return R.string.islesser;
|
||||
case IS_EQUAL_OR_LESSER:
|
||||
return R.string.isequalorlesser;
|
||||
case IS_EQUAL:
|
||||
return R.string.isequal;
|
||||
case IS_EQUAL_OR_GREATER:
|
||||
return R.string.isequalorgreater;
|
||||
case IS_GREATER:
|
||||
return R.string.isgreater;
|
||||
case IS_NOT_AVAILABLE:
|
||||
return R.string.isnotavailable;
|
||||
default:
|
||||
return R.string.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public <T extends Comparable> boolean check(T obj1, T obj2) {
|
||||
if (obj1 == null || obj2 == null)
|
||||
return this.equals(IS_NOT_AVAILABLE);
|
||||
|
||||
int comparison = obj1.compareTo(obj2);
|
||||
switch (this) {
|
||||
case IS_LESSER:
|
||||
return comparison < 0;
|
||||
case IS_EQUAL_OR_LESSER:
|
||||
return comparison <= 0;
|
||||
case IS_EQUAL:
|
||||
return comparison == 0;
|
||||
case IS_EQUAL_OR_GREATER:
|
||||
return comparison >= 0;
|
||||
case IS_GREATER:
|
||||
return comparison > 0;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> labels() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Compare c : Compare.values()) {
|
||||
list.add(MainApp.gs(c.getStringRes()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private Compare compare = Compare.IS_EQUAL;
|
||||
|
||||
public Comparator() {
|
||||
super();
|
||||
}
|
||||
|
||||
public Comparator(Comparator another) {
|
||||
super();
|
||||
compare = another.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
Spinner spinner = new Spinner(root.getContext());
|
||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, Compare.labels());
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(spinnerArrayAdapter);
|
||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
|
||||
spinner.setLayoutParams(spinnerParams);
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
compare = Compare.values()[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
spinner.setSelection(compare.ordinal());
|
||||
root.addView(spinner);
|
||||
|
||||
}
|
||||
|
||||
public Compare getValue() {
|
||||
return compare;
|
||||
}
|
||||
|
||||
public Comparator setValue(Compare compare) {
|
||||
this.compare = compare;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,88 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Spinner
|
||||
import androidx.annotation.StringRes
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.util.*
|
||||
|
||||
class Comparator(mainApp: MainApp) : Element(mainApp) {
|
||||
enum class Compare {
|
||||
IS_LESSER,
|
||||
IS_EQUAL_OR_LESSER,
|
||||
IS_EQUAL,
|
||||
IS_EQUAL_OR_GREATER,
|
||||
IS_GREATER,
|
||||
IS_NOT_AVAILABLE;
|
||||
|
||||
@get:StringRes val stringRes: Int
|
||||
get() = when (this) {
|
||||
IS_LESSER -> R.string.islesser
|
||||
IS_EQUAL_OR_LESSER -> R.string.isequalorlesser
|
||||
IS_EQUAL -> R.string.isequal
|
||||
IS_EQUAL_OR_GREATER -> R.string.isequalorgreater
|
||||
IS_GREATER -> R.string.isgreater
|
||||
IS_NOT_AVAILABLE -> R.string.isnotavailable
|
||||
}
|
||||
|
||||
fun <T : Comparable<T>> check(obj1: T, obj2: T): Boolean {
|
||||
val comparison = obj1.compareTo(obj2)
|
||||
return when (this) {
|
||||
IS_LESSER -> comparison < 0
|
||||
IS_EQUAL_OR_LESSER -> comparison <= 0
|
||||
IS_EQUAL -> comparison == 0
|
||||
IS_EQUAL_OR_GREATER -> comparison >= 0
|
||||
IS_GREATER -> comparison > 0
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun labels(resourceHelper: ResourceHelper): List<String> {
|
||||
val list: MutableList<String> = ArrayList()
|
||||
for (c in values()) {
|
||||
list.add(resourceHelper.gs(c.stringRes))
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, value : Compare) : this(mainApp) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
var value = Compare.IS_EQUAL
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val spinner = Spinner(root.context)
|
||||
val spinnerArrayAdapter = ArrayAdapter(root.context, R.layout.spinner_centered, Compare.labels(resourceHelper))
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
spinner.adapter = spinnerArrayAdapter
|
||||
val spinnerParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
|
||||
spinner.layoutParams = spinnerParams
|
||||
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
value = Compare.values()[position]
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
spinner.setSelection(value.ordinal)
|
||||
root.addView(spinner)
|
||||
}
|
||||
|
||||
fun setValue(compare: Compare): Comparator {
|
||||
value = compare
|
||||
return this
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
public class ComparatorExists extends Element {
|
||||
public enum Compare {
|
||||
EXISTS,
|
||||
NOT_EXISTS;
|
||||
|
||||
public @StringRes
|
||||
int getStringRes() {
|
||||
switch (this) {
|
||||
case EXISTS:
|
||||
return R.string.exists;
|
||||
case NOT_EXISTS:
|
||||
return R.string.notexists;
|
||||
default:
|
||||
return R.string.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> labels() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Compare c : Compare.values()) {
|
||||
list.add(MainApp.gs(c.getStringRes()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private Compare compare = Compare.EXISTS;
|
||||
|
||||
public ComparatorExists() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ComparatorExists(ComparatorExists another) {
|
||||
super();
|
||||
compare = another.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
Spinner spinner = new Spinner(root.getContext());
|
||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, Compare.labels());
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(spinnerArrayAdapter);
|
||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.MATCH_PARENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
|
||||
spinner.setLayoutParams(spinnerParams);
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
compare = Compare.values()[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
spinner.setSelection(compare.ordinal());
|
||||
root.addView(spinner);
|
||||
|
||||
}
|
||||
|
||||
public Compare getValue() {
|
||||
return compare;
|
||||
}
|
||||
|
||||
public ComparatorExists setValue(Compare compare) {
|
||||
this.compare = compare;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Spinner
|
||||
import androidx.annotation.StringRes
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.util.*
|
||||
|
||||
class ComparatorExists(mainApp: MainApp) : Element(mainApp) {
|
||||
enum class Compare {
|
||||
EXISTS, NOT_EXISTS;
|
||||
|
||||
@get:StringRes val stringRes: Int
|
||||
get() = when (this) {
|
||||
EXISTS -> R.string.exists
|
||||
NOT_EXISTS -> R.string.notexists
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun labels(resourceHelper: ResourceHelper): List<String> {
|
||||
val list: MutableList<String> = ArrayList()
|
||||
for (c in values()) list.add(resourceHelper.gs(c.stringRes))
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, value: Compare) : this(mainApp) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
var value = Compare.EXISTS
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val spinner = Spinner(root.context)
|
||||
val spinnerArrayAdapter = ArrayAdapter(root.context, R.layout.spinner_centered, Compare.labels(resourceHelper))
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
spinner.adapter = spinnerArrayAdapter
|
||||
val spinnerParams = LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)
|
||||
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
|
||||
spinner.layoutParams = spinnerParams
|
||||
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
value = Compare.values()[position]
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
spinner.setSelection(value.ordinal)
|
||||
root.addView(spinner)
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public abstract class Element {
|
||||
public abstract void addToLayout(LinearLayout root);
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import javax.inject.Inject
|
||||
|
||||
abstract class Element(val mainApp: MainApp) {
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
|
||||
|
||||
abstract fun addToLayout(root: LinearLayout)
|
||||
|
||||
init {
|
||||
mainApp.androidInjector().inject(this)
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
||||
public class InputBg extends Element {
|
||||
static final int MMOL_MIN = 3;
|
||||
static final int MMOL_MAX = 20;
|
||||
static final int MGDL_MIN = 54;
|
||||
static final int MGDL_MAX = 360;
|
||||
|
||||
private String units = Constants.MGDL;
|
||||
private double value;
|
||||
double minValue;
|
||||
private double maxValue;
|
||||
private double step;
|
||||
private DecimalFormat decimalFormat;
|
||||
|
||||
public InputBg() {
|
||||
super();
|
||||
setUnits(ProfileFunctions.getSystemUnits());
|
||||
if (getUnits().equals(Constants.MMOL))
|
||||
value = MMOL_MIN;
|
||||
else
|
||||
value = MGDL_MIN;
|
||||
}
|
||||
|
||||
public InputBg(InputBg another) {
|
||||
super();
|
||||
value = another.getValue();
|
||||
setUnits(another.getUnits());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||
numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, null);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
||||
public InputBg setUnits(String units) {
|
||||
// set default initial value
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
// mmol
|
||||
minValue = MMOL_MIN;
|
||||
maxValue = MMOL_MAX;
|
||||
step = 0.1;
|
||||
decimalFormat = new DecimalFormat("0.0");
|
||||
} else {
|
||||
// mg/dL
|
||||
minValue = MGDL_MIN;
|
||||
maxValue = MGDL_MAX;
|
||||
step = 1;
|
||||
decimalFormat = new DecimalFormat("0");
|
||||
}
|
||||
|
||||
this.units = units;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InputBg setValue(double value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.NumberPicker
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class InputBg(mainApp: MainApp) : Element(mainApp) {
|
||||
var units = Constants.MGDL
|
||||
var value = 0.0
|
||||
private var minValue = 0.0
|
||||
private var maxValue = 0.0
|
||||
private var step = 0.0
|
||||
private var decimalFormat: DecimalFormat? = null
|
||||
|
||||
|
||||
|
||||
constructor(mainApp: MainApp, value : Double, units: String) : this(mainApp) {
|
||||
setUnits(units)
|
||||
this.value = value
|
||||
}
|
||||
|
||||
init {
|
||||
setUnits(profileFunction.getUnits())
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val numberPicker = NumberPicker(root.context, null)
|
||||
numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, false, root.findViewById(R.id.ok))
|
||||
numberPicker.setOnValueChangedListener { value: Double -> this.value = value }
|
||||
root.addView(numberPicker)
|
||||
}
|
||||
|
||||
fun setUnits(units: String): InputBg {
|
||||
if (units == Constants.MMOL) {
|
||||
minValue = MMOL_MIN
|
||||
maxValue = MMOL_MAX
|
||||
step = 0.1
|
||||
decimalFormat = DecimalFormat("0.0")
|
||||
} else {
|
||||
minValue = MGDL_MIN
|
||||
maxValue = MGDL_MAX
|
||||
step = 1.0
|
||||
decimalFormat = DecimalFormat("0")
|
||||
}
|
||||
this.units = units
|
||||
return this
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MMOL_MIN = 3.0
|
||||
const val MMOL_MAX = 20.0
|
||||
const val MGDL_MIN = 54.0
|
||||
const val MGDL_MAX = 360.0
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public class InputButton extends Element {
|
||||
|
||||
String text;
|
||||
Runnable runnable;
|
||||
|
||||
public InputButton(String text, Runnable runnable) {
|
||||
this.text = text;
|
||||
this.runnable = runnable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
Button button = new Button(root.getContext());
|
||||
|
||||
button.setText(text);
|
||||
button.setOnClickListener(view -> {
|
||||
if (runnable != null)
|
||||
runnable.run();
|
||||
});
|
||||
|
||||
root.addView(button);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.Button
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.MainApp
|
||||
|
||||
class InputButton(mainApp: MainApp) : Element(mainApp) {
|
||||
var text: String? = null
|
||||
var runnable: Runnable? = null
|
||||
|
||||
constructor(mainApp: MainApp, text: String, runnable: Runnable) : this(mainApp) {
|
||||
this.text = text
|
||||
this.runnable = runnable
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val button = Button(root.context)
|
||||
button.text = text
|
||||
button.setOnClickListener { runnable?.run() }
|
||||
root.addView(button)
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
||||
public class InputDelta extends Element {
|
||||
private Comparator.Compare compare = Comparator.Compare.IS_EQUAL;
|
||||
|
||||
public enum DeltaType {
|
||||
DELTA,
|
||||
SHORT_AVERAGE,
|
||||
LONG_AVERAGE;
|
||||
|
||||
public @StringRes
|
||||
int getStringRes() {
|
||||
switch (this) {
|
||||
case DELTA:
|
||||
return R.string.delta;
|
||||
case SHORT_AVERAGE:
|
||||
return R.string.short_avgdelta;
|
||||
case LONG_AVERAGE:
|
||||
return R.string.long_avgdelta;
|
||||
default:
|
||||
return R.string.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> labels() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (DeltaType d : DeltaType.values()) {
|
||||
list.add(MainApp.gs(d.getStringRes()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
private double value;
|
||||
double minValue;
|
||||
double maxValue;
|
||||
private double step;
|
||||
private DecimalFormat decimalFormat;
|
||||
private DeltaType deltaType;
|
||||
|
||||
NumberPicker numberPicker;
|
||||
|
||||
public InputDelta() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InputDelta(double value, double minValue, double maxValue, double step, DecimalFormat decimalFormat, DeltaType deltaType) {
|
||||
super();
|
||||
this.value = value;
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
this.step = step;
|
||||
this.decimalFormat = decimalFormat;
|
||||
this.deltaType = deltaType;
|
||||
}
|
||||
|
||||
public InputDelta(InputDelta another) {
|
||||
super();
|
||||
value = another.getValue();
|
||||
minValue = another.minValue;
|
||||
maxValue = another.maxValue;
|
||||
step = another.step;
|
||||
decimalFormat = another.decimalFormat;
|
||||
deltaType = another.deltaType;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
Spinner spinner = new Spinner(root.getContext());
|
||||
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<>(root.getContext(), R.layout.spinner_centered, DeltaType.labels());
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(spinnerArrayAdapter);
|
||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
|
||||
spinner.setLayoutParams(spinnerParams);
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
deltaType = DeltaType.values()[position];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
spinner.setSelection(this.deltaType.ordinal());
|
||||
// root.addView(spinner);
|
||||
numberPicker = new NumberPicker(root.getContext(), null);
|
||||
numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, null);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
LinearLayout l = new LinearLayout(root.getContext());
|
||||
l.setOrientation(LinearLayout.VERTICAL);
|
||||
l.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
l.addView(spinner);
|
||||
l.addView(numberPicker);
|
||||
root.addView(l);
|
||||
}
|
||||
|
||||
public InputDelta setValue(double value, DeltaType type) {
|
||||
this.value = value;
|
||||
this.deltaType = type;
|
||||
if (numberPicker != null)
|
||||
numberPicker.setValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public DeltaType getDeltaType() {
|
||||
return deltaType;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Spinner
|
||||
import androidx.annotation.StringRes
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.NumberPicker
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
|
||||
class InputDelta(mainApp: MainApp) : Element(mainApp) {
|
||||
enum class DeltaType {
|
||||
DELTA, SHORT_AVERAGE, LONG_AVERAGE;
|
||||
|
||||
@get:StringRes val stringRes: Int
|
||||
get() = when (this) {
|
||||
DELTA -> R.string.delta
|
||||
SHORT_AVERAGE -> R.string.short_avgdelta
|
||||
LONG_AVERAGE -> R.string.long_avgdelta
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun labels(resourceHelper: ResourceHelper): List<String> {
|
||||
val list: MutableList<String> = ArrayList()
|
||||
for (d in values()) {
|
||||
list.add(resourceHelper.gs(d.stringRes))
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var value = 0.0
|
||||
private var minValue = 0.0
|
||||
private var maxValue = 0.0
|
||||
private var step = 0.0
|
||||
private var decimalFormat: DecimalFormat? = null
|
||||
var deltaType: DeltaType = DeltaType.DELTA
|
||||
|
||||
constructor(mainApp: MainApp, value: Double, minValue: Double, maxValue: Double, step: Double, decimalFormat: DecimalFormat, deltaType: DeltaType) : this(mainApp) {
|
||||
this.value = value
|
||||
this.minValue = minValue
|
||||
this.maxValue = maxValue
|
||||
this.step = step
|
||||
this.decimalFormat = decimalFormat
|
||||
this.deltaType = deltaType
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, inputDelta: InputDelta) : this(mainApp) {
|
||||
value = inputDelta.value
|
||||
minValue = inputDelta.minValue
|
||||
maxValue = inputDelta.maxValue
|
||||
step = inputDelta.step
|
||||
decimalFormat = inputDelta.decimalFormat
|
||||
deltaType = inputDelta.deltaType
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val spinner = Spinner(root.context)
|
||||
val spinnerArrayAdapter = ArrayAdapter(root.context, R.layout.spinner_centered, DeltaType.labels(resourceHelper))
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
spinner.adapter = spinnerArrayAdapter
|
||||
val spinnerParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
|
||||
spinner.layoutParams = spinnerParams
|
||||
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
deltaType = DeltaType.values()[position]
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
spinner.setSelection(deltaType.ordinal)
|
||||
val numberPicker = NumberPicker(root.context, null)
|
||||
numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, null)
|
||||
numberPicker.setOnValueChangedListener { value: Double -> this.value = value }
|
||||
val l = LinearLayout(root.context)
|
||||
l.orientation = LinearLayout.VERTICAL
|
||||
l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
l.addView(spinner)
|
||||
l.addView(numberPicker)
|
||||
root.addView(l)
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
||||
public class InputDouble extends Element {
|
||||
|
||||
final TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
};
|
||||
|
||||
private double value;
|
||||
private double minValue;
|
||||
private double maxValue;
|
||||
private double step;
|
||||
private DecimalFormat decimalFormat;
|
||||
|
||||
NumberPicker numberPicker;
|
||||
|
||||
public InputDouble() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InputDouble(double value, double minValue, double maxValue, double step, DecimalFormat decimalFormat) {
|
||||
super();
|
||||
this.value = value;
|
||||
this.minValue = minValue;
|
||||
this.maxValue = maxValue;
|
||||
this.step = step;
|
||||
this.decimalFormat = decimalFormat;
|
||||
}
|
||||
|
||||
public InputDouble(InputDouble another) {
|
||||
super();
|
||||
value = another.getValue();
|
||||
minValue = another.minValue;
|
||||
maxValue = another.maxValue;
|
||||
step = another.step;
|
||||
decimalFormat = another.decimalFormat;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
numberPicker = new NumberPicker(root.getContext(), null);
|
||||
numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, textWatcher);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
public InputDouble setValue(double value) {
|
||||
this.value = value;
|
||||
if (numberPicker != null)
|
||||
numberPicker.setValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.NumberPicker
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class InputDouble(mainApp: MainApp) : Element(mainApp) {
|
||||
var value = 0.0
|
||||
private var minValue = 0.0
|
||||
private var maxValue = 0.0
|
||||
private var step = 0.0
|
||||
private var decimalFormat: DecimalFormat? = null
|
||||
private var numberPicker: NumberPicker? = null
|
||||
|
||||
constructor(mainApp: MainApp, value: Double, minValue: Double, maxValue: Double, step: Double, decimalFormat: DecimalFormat) : this(mainApp) {
|
||||
this.value = value
|
||||
this.minValue = minValue
|
||||
this.maxValue = maxValue
|
||||
this.step = step
|
||||
this.decimalFormat = decimalFormat
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, inputDouble: InputDouble) : this(mainApp) {
|
||||
this.value = inputDouble.value
|
||||
this.minValue = inputDouble.minValue
|
||||
this.maxValue = inputDouble.maxValue
|
||||
this.step = inputDouble.step
|
||||
this.decimalFormat = inputDouble.decimalFormat
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
numberPicker = NumberPicker(root.context, null)
|
||||
numberPicker?.setParams(value, minValue, maxValue, step, decimalFormat, true, root.findViewById(R.id.ok))
|
||||
numberPicker?.setOnValueChangedListener { value: Double -> this.value = value }
|
||||
root.addView(numberPicker)
|
||||
}
|
||||
|
||||
fun setValue(value: Double): InputDouble {
|
||||
this.value = value
|
||||
numberPicker?.value = value
|
||||
return this
|
||||
}
|
||||
}
|
|
@ -1,66 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
||||
public class InputDuration extends Element {
|
||||
public enum TimeUnit {
|
||||
MINUTES,
|
||||
HOURS
|
||||
}
|
||||
|
||||
private TimeUnit unit;
|
||||
private int value;
|
||||
|
||||
public InputDuration(int value, TimeUnit unit) {
|
||||
this.unit = unit;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public InputDuration(InputDuration another) {
|
||||
unit = another.unit;
|
||||
value = another.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||
if (unit.equals(TimeUnit.MINUTES)) {
|
||||
// Minutes
|
||||
numberPicker.setParams(0d, 0d, 24 * 60d, 10d, new DecimalFormat("0"), false, null);
|
||||
} else {
|
||||
// Hours
|
||||
numberPicker.setParams(0d, 0d, 24d, 1d, new DecimalFormat("0"), false, null);
|
||||
}
|
||||
numberPicker.setValue((double) value);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = (int) value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
TimeUnit getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setMinutes(int value) {
|
||||
if (unit.equals(TimeUnit.MINUTES)) {
|
||||
this.value = value;
|
||||
} else {
|
||||
this.value = value / 60;
|
||||
}
|
||||
}
|
||||
|
||||
public int getMinutes() {
|
||||
if (unit.equals(TimeUnit.MINUTES)) {
|
||||
return value;
|
||||
} else {
|
||||
return value * 60;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.NumberPicker
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class InputDuration(mainApp: MainApp) : Element(mainApp) {
|
||||
enum class TimeUnit {
|
||||
MINUTES, HOURS
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, value: Int, unit: TimeUnit) : this(mainApp) {
|
||||
this.unit = unit
|
||||
this.value = value
|
||||
}
|
||||
|
||||
var unit: TimeUnit = TimeUnit.MINUTES
|
||||
var value: Int = 0
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val numberPicker = NumberPicker(root.context, null)
|
||||
if (unit == TimeUnit.MINUTES)
|
||||
numberPicker.setParams(0.0, 0.0, 24 * 60.0, 10.0, DecimalFormat("0"), false, root.findViewById(R.id.ok))
|
||||
else
|
||||
numberPicker.setParams(0.0, 0.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)
|
||||
}
|
||||
|
||||
fun duplicate(): InputDuration {
|
||||
val i = InputDuration(mainApp)
|
||||
i.unit = unit
|
||||
i.value = value
|
||||
return i
|
||||
}
|
||||
|
||||
fun getMinutes(): Int = if (unit == TimeUnit.MINUTES) value else value * 60
|
||||
|
||||
fun setMinutes(value: Int): InputDuration {
|
||||
if (unit == TimeUnit.MINUTES)
|
||||
this.value = value
|
||||
else
|
||||
this.value = value / 60
|
||||
return this
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
||||
public class InputInsulin extends Element {
|
||||
|
||||
final TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
value = Math.max(value, -20d);
|
||||
value = Math.min(value, 20d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
};
|
||||
|
||||
private double value;
|
||||
|
||||
public InputInsulin() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InputInsulin(InputInsulin another) {
|
||||
super();
|
||||
value = another.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||
numberPicker.setParams(0d, -20d, 20d, 0.1, new DecimalFormat("0.0"), true, null, textWatcher);
|
||||
numberPicker.setValue(value);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public InputInsulin setValue(double value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.NumberPicker
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class InputInsulin(mainApp: MainApp) : Element(mainApp) {
|
||||
var value = 0.0
|
||||
|
||||
constructor(mainApp: MainApp, another: InputInsulin) : this(mainApp) {
|
||||
value = another.value
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val numberPicker = NumberPicker(root.context, null)
|
||||
numberPicker.setParams(0.0, -20.0, 20.0, 0.1, DecimalFormat("0.0"), true, root.findViewById(R.id.ok))
|
||||
numberPicker.value = value
|
||||
numberPicker.setOnValueChangedListener { value: Double -> this.value = value }
|
||||
root.addView(numberPicker)
|
||||
}
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
public class InputLocationMode extends Element {
|
||||
|
||||
public enum Mode {
|
||||
INSIDE,
|
||||
OUTSIDE,
|
||||
GOING_IN,
|
||||
GOING_OUT;
|
||||
|
||||
public @StringRes
|
||||
int getStringRes() {
|
||||
switch (this) {
|
||||
case INSIDE:
|
||||
return R.string.location_inside;
|
||||
case OUTSIDE:
|
||||
return R.string.location_outside;
|
||||
case GOING_IN:
|
||||
return R.string.location_going_in;
|
||||
case GOING_OUT:
|
||||
return R.string.location_going_out;
|
||||
default:
|
||||
return R.string.unknown;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> labels() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Mode c : Mode.values()) {
|
||||
list.add(MainApp.gs(c.getStringRes()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public Mode fromString(String wanted){
|
||||
for (Mode c : Mode.values()) {
|
||||
if(c.toString() == wanted)
|
||||
return c;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Mode mode;
|
||||
|
||||
public InputLocationMode() {
|
||||
super();
|
||||
mode = Mode.INSIDE;
|
||||
}
|
||||
|
||||
public InputLocationMode(InputLocationMode another) {
|
||||
super();
|
||||
this.mode = another.mode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
ArrayAdapter<String> adapter = new ArrayAdapter<>(root.getContext(),
|
||||
R.layout.spinner_centered, Mode.labels());
|
||||
Spinner spinner = new Spinner(root.getContext());
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(adapter);
|
||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
|
||||
spinner.setLayoutParams(spinnerParams);
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
setValue(Mode.values()[position]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
spinner.setSelection(this.getValue().ordinal());
|
||||
root.addView(spinner);
|
||||
|
||||
}
|
||||
|
||||
public Mode getValue() {
|
||||
return mode;
|
||||
}
|
||||
|
||||
public InputLocationMode setValue(Mode mode) {
|
||||
this.mode = mode;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Spinner
|
||||
import androidx.annotation.StringRes
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import java.util.*
|
||||
|
||||
class InputLocationMode(mainApp: MainApp) : Element(mainApp) {
|
||||
enum class Mode {
|
||||
INSIDE, OUTSIDE, GOING_IN, GOING_OUT;
|
||||
|
||||
@get:StringRes val stringRes: Int
|
||||
get() = when (this) {
|
||||
INSIDE -> R.string.location_inside
|
||||
OUTSIDE -> R.string.location_outside
|
||||
GOING_IN -> R.string.location_going_in
|
||||
GOING_OUT -> R.string.location_going_out
|
||||
}
|
||||
|
||||
fun fromString(wanted: String): Mode {
|
||||
for (c in values()) {
|
||||
if (c.toString() === wanted) return c
|
||||
}
|
||||
throw IllegalStateException("Invalid parameter")
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun labels(resourceHelper: ResourceHelper): List<String> {
|
||||
val list: MutableList<String> = ArrayList()
|
||||
for (c in values()) {
|
||||
list.add(resourceHelper.gs(c.stringRes))
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var value: Mode = Mode.INSIDE
|
||||
|
||||
constructor(mainApp: MainApp, value: InputLocationMode.Mode) : this(mainApp) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val adapter = ArrayAdapter(root.context, R.layout.spinner_centered, Mode.labels(resourceHelper))
|
||||
val spinner = Spinner(root.context)
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
spinner.adapter = adapter
|
||||
val spinnerParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
|
||||
spinner.layoutParams = spinnerParams
|
||||
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
value = Mode.values()[position]
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
spinner.setSelection(value.ordinal)
|
||||
root.addView(spinner)
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
||||
public class InputPercent extends Element {
|
||||
|
||||
final TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
value = Math.max(value, 70d);
|
||||
value = Math.min(value, 130d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
};
|
||||
|
||||
private double value;
|
||||
|
||||
public InputPercent() {
|
||||
super();
|
||||
value = 100d;
|
||||
}
|
||||
|
||||
public InputPercent(InputPercent another) {
|
||||
super();
|
||||
value = another.getValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||
numberPicker.setParams(100d, 70d, 130d, 5d, new DecimalFormat("0"), true, null, textWatcher);
|
||||
numberPicker.setValue(value);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public InputPercent setValue(double value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.NumberPicker
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class InputPercent(mainApp: MainApp) : Element(mainApp) {
|
||||
var value: Double = 100.0
|
||||
|
||||
constructor(mainApp: MainApp, value: Double) : this(mainApp) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val numberPicker = NumberPicker(root.context, null)
|
||||
numberPicker.setParams(100.0, MIN, MAX, 5.0, DecimalFormat("0"), true, root.findViewById(R.id.ok))
|
||||
numberPicker.value = value
|
||||
numberPicker.setOnValueChangedListener { value: Double -> this.value = value }
|
||||
root.addView(numberPicker)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MIN = 70.0
|
||||
const val MAX = 130.0
|
||||
}
|
||||
}
|
|
@ -1,99 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.Spinner;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.data.ProfileStore;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
|
||||
public class InputProfileName extends Element {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
ProfileStore profileStore;
|
||||
|
||||
String profileName;
|
||||
|
||||
public InputProfileName(String name) {
|
||||
super();
|
||||
this.profileName = name;
|
||||
}
|
||||
|
||||
public InputProfileName(InputProfileName another) {
|
||||
super();
|
||||
profileName = another.getValue();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
ArrayList<CharSequence> profileList = new ArrayList<>();
|
||||
profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
|
||||
if (profileStore == null) {
|
||||
log.error("ProfileStore is empty");
|
||||
} else {
|
||||
profileList = profileStore.getProfileList();
|
||||
}
|
||||
ArrayAdapter<CharSequence> adapter = new ArrayAdapter<>(root.getContext(),
|
||||
R.layout.spinner_centered, profileList);
|
||||
Spinner spinner = new Spinner(root.getContext());
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
||||
spinner.setAdapter(adapter);
|
||||
LinearLayout.LayoutParams spinnerParams = new LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
);
|
||||
spinnerParams.setMargins(0, MainApp.dpToPx(4), 0, MainApp.dpToPx(4));
|
||||
spinner.setLayoutParams(spinnerParams);
|
||||
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
setValue(listNames().get(position).toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
}
|
||||
});
|
||||
spinner.setSelection(0);
|
||||
LinearLayout l = new LinearLayout(root.getContext());
|
||||
l.setOrientation(LinearLayout.VERTICAL);
|
||||
l.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
l.addView(spinner);
|
||||
root.addView(l);
|
||||
}
|
||||
|
||||
public InputProfileName setValue(String name) {
|
||||
this.profileName = name;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return profileName;
|
||||
}
|
||||
|
||||
public ArrayList<CharSequence> listNames(){
|
||||
ArrayList<CharSequence> profileList = new ArrayList<>();
|
||||
// profile
|
||||
profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile();
|
||||
if (profileStore == null) {
|
||||
log.error("ProfileStore is empty");
|
||||
} else {
|
||||
profileList = profileStore.getProfileList();
|
||||
}
|
||||
return profileList;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.Spinner
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
|
||||
class InputProfileName(mainApp: MainApp) : Element(mainApp) {
|
||||
var value: String = ""
|
||||
|
||||
constructor(mainApp: MainApp, name: String) : this(mainApp) {
|
||||
value = name
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val profileStore = ConfigBuilderPlugin.getPlugin().activeProfileInterface.profile ?: return
|
||||
val profileList = profileStore.getProfileList()
|
||||
val adapter = ArrayAdapter(root.context, R.layout.spinner_centered, profileList)
|
||||
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
val spinner = Spinner(root.context)
|
||||
spinner.adapter = adapter
|
||||
val spinnerParams = LinearLayout.LayoutParams(
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT,
|
||||
LinearLayout.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
spinnerParams.setMargins(0, resourceHelper.dpToPx(4), 0, resourceHelper.dpToPx(4))
|
||||
spinner.layoutParams = spinnerParams
|
||||
spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) {
|
||||
value = profileList[position].toString()
|
||||
}
|
||||
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {}
|
||||
}
|
||||
spinner.setSelection(0)
|
||||
val l = LinearLayout(root.context)
|
||||
l.orientation = LinearLayout.VERTICAL
|
||||
l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
l.addView(spinner)
|
||||
root.addView(l)
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
public class InputString extends Element {
|
||||
|
||||
TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
value = s.toString();
|
||||
}
|
||||
};
|
||||
|
||||
private String value = "";
|
||||
|
||||
public InputString() {
|
||||
super();
|
||||
}
|
||||
|
||||
public InputString(InputString another) {
|
||||
super();
|
||||
value = another.getValue();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
EditText editText = new EditText(root.getContext());
|
||||
editText.setText(value);
|
||||
editText.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
editText.addTextChangedListener(textWatcher);
|
||||
root.addView(editText);
|
||||
}
|
||||
|
||||
public InputString setValue(String value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.MainApp
|
||||
|
||||
class InputString(mainApp: MainApp) : Element(mainApp) {
|
||||
var textWatcher: TextWatcher = object : TextWatcher {
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
|
||||
override fun afterTextChanged(s: Editable) {
|
||||
value = s.toString()
|
||||
}
|
||||
}
|
||||
var value = ""
|
||||
|
||||
constructor(mainApp: MainApp, value: String) : this(mainApp) {
|
||||
this.value = value
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
val editText = EditText(root.context)
|
||||
editText.setText(value)
|
||||
editText.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
editText.addTextChangedListener(textWatcher)
|
||||
root.addView(editText)
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.utils.NumberPicker;
|
||||
|
||||
public class InputTempTarget extends Element {
|
||||
|
||||
private String units = Constants.MGDL;
|
||||
private double value;
|
||||
double minValue;
|
||||
private double maxValue;
|
||||
private double step;
|
||||
private DecimalFormat decimalFormat;
|
||||
|
||||
private final TextWatcher textWatcher = new TextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
value = Math.max(minValue, value);
|
||||
value = Math.min(maxValue, value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
};
|
||||
|
||||
public InputTempTarget() {
|
||||
super();
|
||||
setUnits(ProfileFunctions.getSystemUnits());
|
||||
if (getUnits().equals(Constants.MMOL))
|
||||
value = 6;
|
||||
else
|
||||
value = 110;
|
||||
}
|
||||
|
||||
public InputTempTarget(InputTempTarget another) {
|
||||
super();
|
||||
value = another.getValue();
|
||||
setUnits(another.getUnits());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
|
||||
numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, null, textWatcher);
|
||||
numberPicker.setOnValueChangedListener(value -> this.value = value);
|
||||
root.addView(numberPicker);
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return units;
|
||||
}
|
||||
|
||||
public InputTempTarget setUnits(String units) {
|
||||
// set default initial value
|
||||
if (units.equals(Constants.MMOL)) {
|
||||
// mmol
|
||||
minValue = Constants.MIN_TT_MMOL;
|
||||
maxValue = Constants.MAX_TT_MMOL;
|
||||
step = 0.1;
|
||||
decimalFormat = new DecimalFormat("0.0");
|
||||
} else {
|
||||
// mg/dL
|
||||
minValue = Constants.MIN_TT_MGDL;
|
||||
maxValue = Constants.MAX_TT_MGDL;
|
||||
step = 1;
|
||||
decimalFormat = new DecimalFormat("0");
|
||||
}
|
||||
|
||||
this.units = units;
|
||||
return this;
|
||||
}
|
||||
|
||||
public InputTempTarget setValue(double value) {
|
||||
this.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.utils.NumberPicker
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class InputTempTarget(mainApp: MainApp) : Element(mainApp) {
|
||||
var units = Constants.MGDL
|
||||
var value = 0.0
|
||||
|
||||
init {
|
||||
value = if (units == Constants.MMOL) 6.0 else 110.0
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, inputTempTarget: InputTempTarget) : this(mainApp) {
|
||||
value = inputTempTarget.value
|
||||
units = inputTempTarget.units
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) {
|
||||
var minValue = 0.0
|
||||
var maxValue = 0.0
|
||||
var step = 0.0
|
||||
var decimalFormat: DecimalFormat? = null
|
||||
if (units == Constants.MMOL) { // mmol
|
||||
minValue = Constants.MIN_TT_MMOL
|
||||
maxValue = Constants.MAX_TT_MMOL
|
||||
step = 0.1
|
||||
decimalFormat = DecimalFormat("0.0")
|
||||
} else { // mg/dL
|
||||
minValue = Constants.MIN_TT_MGDL
|
||||
maxValue = Constants.MAX_TT_MGDL
|
||||
step = 1.0
|
||||
decimalFormat = DecimalFormat("0")
|
||||
}
|
||||
val numberPicker = NumberPicker(root.context, null)
|
||||
numberPicker.setParams(value, minValue, maxValue, step, decimalFormat, true, root.findViewById(R.id.ok))
|
||||
numberPicker.setOnValueChangedListener { value: Double -> this.value = value }
|
||||
root.addView(numberPicker)
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
|
||||
public class LabelWithElement extends Element {
|
||||
final Element element;
|
||||
final String textPre;
|
||||
final String textPost;
|
||||
|
||||
public LabelWithElement(String textPre, String textPost, Element element) {
|
||||
this.element = element;
|
||||
this.textPre = textPre;
|
||||
this.textPost = textPost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
// container layout
|
||||
LinearLayout layout = new LinearLayout(root.getContext());
|
||||
layout.setOrientation(LinearLayout.HORIZONTAL);
|
||||
layout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
// text view pre element
|
||||
int px = MainApp.dpToPx(10);
|
||||
TextView textViewPre = new TextView(root.getContext());
|
||||
textViewPre.setText(textPre);
|
||||
textViewPre.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
//textViewPre.setWidth(MainApp.dpToPx(120));
|
||||
textViewPre.setPadding(px, px, px, px);
|
||||
textViewPre.setTypeface(textViewPre.getTypeface(), Typeface.BOLD);
|
||||
layout.addView(textViewPre);
|
||||
|
||||
TextView spacer = new TextView(root.getContext());
|
||||
spacer.setLayoutParams(new TableLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f));
|
||||
layout.addView(spacer);
|
||||
|
||||
// add element to layout
|
||||
element.addToLayout(layout);
|
||||
|
||||
// text view post element
|
||||
if (textPost != null) {
|
||||
px = MainApp.dpToPx(5);
|
||||
TextView textViewPost = new TextView(root.getContext());
|
||||
textViewPost.setText(textPost);
|
||||
textViewPost.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
//textViewPost.setWidth(MainApp.dpToPx(45));
|
||||
textViewPost.setPadding(px, px, px, px);
|
||||
textViewPost.setTypeface(textViewPost.getTypeface(), Typeface.BOLD);
|
||||
layout.addView(textViewPost);
|
||||
}
|
||||
|
||||
// add layout to root layout
|
||||
root.addView(layout);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TableLayout
|
||||
import android.widget.TextView
|
||||
import info.nightscout.androidaps.MainApp
|
||||
|
||||
class LabelWithElement(mainApp: MainApp) : Element(mainApp) {
|
||||
var element: Element? = null
|
||||
var textPre: String = ""
|
||||
var textPost: String = ""
|
||||
|
||||
constructor(mainApp: MainApp, textPre: String, textPost: String, element: Element) : this(mainApp) {
|
||||
this.textPre = textPre
|
||||
this.textPost = textPost
|
||||
this.element = element
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) { // container layout
|
||||
val layout = LinearLayout(root.context)
|
||||
layout.orientation = LinearLayout.HORIZONTAL
|
||||
layout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
// text view pre element
|
||||
var px = resourceHelper.dpToPx(10)
|
||||
val textViewPre = TextView(root.context)
|
||||
textViewPre.text = textPre
|
||||
textViewPre.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
//textViewPre.setWidth(MainApp.dpToPx(120));
|
||||
textViewPre.setPadding(px, px, px, px)
|
||||
textViewPre.setTypeface(textViewPre.typeface, Typeface.BOLD)
|
||||
layout.addView(textViewPre)
|
||||
val spacer = TextView(root.context)
|
||||
spacer.layoutParams = TableLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, 1f)
|
||||
layout.addView(spacer)
|
||||
// add element to layout
|
||||
element?.addToLayout(layout)
|
||||
// text view post element
|
||||
px = resourceHelper.dpToPx(5)
|
||||
val textViewPost = TextView(root.context)
|
||||
textViewPost.text = textPost
|
||||
textViewPost.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||
ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
//textViewPost.setWidth(MainApp.dpToPx(45));
|
||||
textViewPost.setPadding(px, px, px, px)
|
||||
textViewPost.setTypeface(textViewPost.typeface, Typeface.BOLD)
|
||||
layout.addView(textViewPost)
|
||||
// add layout to root layout
|
||||
root.addView(layout)
|
||||
}
|
||||
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class LayoutBuilder {
|
||||
ArrayList<Element> mElements = new ArrayList<>();
|
||||
|
||||
public LayoutBuilder add(Element element) {
|
||||
mElements.add(element);
|
||||
return this;
|
||||
}
|
||||
|
||||
public LayoutBuilder add(Element element, boolean condition) {
|
||||
if (condition) mElements.add(element);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build(LinearLayout layout) {
|
||||
for (Element e : mElements) {
|
||||
e.addToLayout(layout);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import java.util.*
|
||||
|
||||
class LayoutBuilder {
|
||||
var mElements = ArrayList<Element>()
|
||||
fun add(element: Element): LayoutBuilder {
|
||||
mElements.add(element)
|
||||
return this
|
||||
}
|
||||
|
||||
fun add(element: Element, condition: Boolean): LayoutBuilder {
|
||||
if (condition) mElements.add(element)
|
||||
return this
|
||||
}
|
||||
|
||||
fun build(layout: LinearLayout) {
|
||||
for (e in mElements) {
|
||||
e.addToLayout(layout)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
|
||||
public class StaticLabel extends Element {
|
||||
String label;
|
||||
|
||||
public StaticLabel(String label) {
|
||||
super();
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
public StaticLabel(int resourceId) {
|
||||
super();
|
||||
this.label = MainApp.gs(resourceId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addToLayout(LinearLayout root) {
|
||||
// text view pre element
|
||||
int px = MainApp.dpToPx(10);
|
||||
TextView textView = new TextView(root.getContext());
|
||||
textView.setText(label);
|
||||
// textViewPre.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
textView.setPadding(px, px, px, px);
|
||||
textView.setTypeface(textView.getTypeface(), Typeface.BOLD);
|
||||
textView.setBackgroundColor(MainApp.gc(R.color.mdtp_line_dark));
|
||||
// add element to layout
|
||||
root.addView(textView);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.elements
|
||||
|
||||
import android.graphics.Typeface
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
|
||||
class StaticLabel(mainApp: MainApp) : Element(mainApp) {
|
||||
var label = ""
|
||||
|
||||
constructor(mainApp: MainApp, label: String) : this(mainApp) {
|
||||
this.label = label
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, resourceId: Int) : this(mainApp) {
|
||||
label = resourceHelper.gs(resourceId)
|
||||
}
|
||||
|
||||
override fun addToLayout(root: LinearLayout) { // text view pre element
|
||||
val px = resourceHelper.dpToPx(10)
|
||||
val textView = TextView(root.context)
|
||||
textView.text = label
|
||||
// textViewPre.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
textView.setPadding(px, px, px, px)
|
||||
textView.setTypeface(textView.typeface, Typeface.BOLD)
|
||||
textView.setBackgroundColor(resourceHelper.gc(R.color.mdtp_line_dark))
|
||||
root.addView(textView)
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public abstract class Trigger {
|
||||
private static final Logger log = LoggerFactory.getLogger(Trigger.class);
|
||||
|
||||
TriggerConnector connector = null;
|
||||
long lastRun;
|
||||
|
||||
Trigger() {
|
||||
}
|
||||
|
||||
public TriggerConnector getConnector() {
|
||||
return connector;
|
||||
}
|
||||
|
||||
public abstract boolean shouldRun();
|
||||
|
||||
|
||||
public abstract String toJSON();
|
||||
|
||||
/*package*/
|
||||
abstract Trigger fromJSON(String data);
|
||||
|
||||
public abstract int friendlyName();
|
||||
|
||||
public abstract String friendlyDescription();
|
||||
|
||||
public abstract Optional<Integer> icon();
|
||||
|
||||
public void executed(long time) {
|
||||
lastRun = time;
|
||||
}
|
||||
|
||||
public long getLastRun() {
|
||||
return lastRun;
|
||||
}
|
||||
|
||||
public abstract Trigger duplicate();
|
||||
|
||||
public static Trigger instantiate(String json) {
|
||||
try {
|
||||
return instantiate(new JSONObject(json));
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Trigger instantiate(JSONObject object) {
|
||||
try {
|
||||
String type = object.getString("type");
|
||||
JSONObject data = object.getJSONObject("data");
|
||||
Class clazz = Class.forName(type);
|
||||
return ((Trigger) clazz.newInstance()).fromJSON(data.toString());
|
||||
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
TextView title = new TextView(root.getContext());
|
||||
title.setText(friendlyName());
|
||||
root.addView(title);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
AppCompatActivity scanForActivity(Context cont) {
|
||||
if (cont == null)
|
||||
return null;
|
||||
else if (cont instanceof AppCompatActivity)
|
||||
return (AppCompatActivity) cont;
|
||||
else if (cont instanceof ContextWrapper)
|
||||
return scanForActivity(((ContextWrapper) cont).getBaseContext());
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.content.Context
|
||||
import android.content.ContextWrapper
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
|
||||
import info.nightscout.androidaps.services.LocationService
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.full.primaryConstructor
|
||||
|
||||
abstract class Trigger(val mainApp: MainApp) {
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var sp : SP
|
||||
@Inject lateinit var locationService: LocationService
|
||||
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
|
||||
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
|
||||
var connector: TriggerConnector? = null
|
||||
|
||||
init {
|
||||
mainApp.androidInjector().inject(this)
|
||||
}
|
||||
|
||||
abstract fun shouldRun(): Boolean
|
||||
abstract fun toJSON(): String
|
||||
abstract fun fromJSON(data: String): Trigger
|
||||
|
||||
abstract fun friendlyName(): Int
|
||||
abstract fun friendlyDescription(): String
|
||||
abstract fun icon(): Optional<Int?>
|
||||
abstract fun duplicate(): Trigger
|
||||
|
||||
open fun generateDialog(root: LinearLayout) {
|
||||
val title = TextView(root.context)
|
||||
title.setText(friendlyName())
|
||||
root.addView(title)
|
||||
}
|
||||
|
||||
fun scanForActivity(cont: Context?): AppCompatActivity? {
|
||||
if (cont == null) return null
|
||||
else if (cont is AppCompatActivity) return cont
|
||||
else if (cont is ContextWrapper) return scanForActivity(cont.baseContext)
|
||||
return null
|
||||
}
|
||||
|
||||
fun instantiate(obj: JSONObject): Trigger? {
|
||||
try {
|
||||
val type = obj.getString("type")
|
||||
val data = obj.getJSONObject("data")
|
||||
val clazz = Class.forName(type).kotlin
|
||||
return (clazz.primaryConstructor?.call(mainApp) as Trigger).fromJSON(data?.toString()
|
||||
?: "")
|
||||
} catch (e: ClassNotFoundException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
} catch (e: InstantiationException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
} catch (e: IllegalAccessException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error("Unhandled exception", e)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerAutosensValue extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
private final int minValue = (int) (SP.getDouble("openapsama_autosens_min", 0.7d) * 100);
|
||||
private final int maxValue = (int) (SP.getDouble("openapsama_autosens_max", 1.2d) * 100);
|
||||
private final double step = 1;
|
||||
private DecimalFormat decimalFormat = new DecimalFormat("1");
|
||||
private InputDouble value = new InputDouble(100, (double) minValue, (double) maxValue, step, decimalFormat);
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerAutosensValue() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerAutosensValue(TriggerAutosensValue triggerAutosensValue) {
|
||||
super();
|
||||
value = new InputDouble(triggerAutosensValue.value);
|
||||
lastRun = triggerAutosensValue.lastRun;
|
||||
comparator = new Comparator(triggerAutosensValue.comparator);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensData("Automation trigger");
|
||||
if (autosensData == null)
|
||||
if (comparator.getValue() == Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
boolean doRun = comparator.getValue().check((autosensData.autosensResult.ratio), getValue() / 100d);
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerAutosensValue.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("value", getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
value.setValue(JsonHelper.safeGetDouble(d, "value"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.autosenslabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.autosenscompared, MainApp.gs(comparator.getValue().getStringRes()), getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.as);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerAutosensValue(this);
|
||||
}
|
||||
|
||||
TriggerAutosensValue setValue(int requestedValue) {
|
||||
this.value.setValue(requestedValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerAutosensValue lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerAutosensValue comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.autosenslabel))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.autosenslabel) + ": ", "", value))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble
|
||||
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.safeGetDouble
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||
import org.json.JSONObject
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class TriggerAutosensValue(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private val minValue = (sp.getDouble(R.string.key_openapsama_autosens_min, 0.7) * 100).toInt()
|
||||
private val maxValue = (sp.getDouble(R.string.key_openapsama_autosens_max, 1.2) * 100).toInt()
|
||||
private val step = 1.0
|
||||
private val decimalFormat = DecimalFormat("1")
|
||||
private var autosens: InputDouble = InputDouble(mainApp, 100.0, minValue.toDouble(), maxValue.toDouble(), step, decimalFormat)
|
||||
|
||||
var comparator: Comparator = Comparator(mainApp)
|
||||
|
||||
private constructor(mainApp: MainApp, triggerAutosensValue: TriggerAutosensValue) : this(mainApp) {
|
||||
autosens = InputDouble(mainApp, triggerAutosensValue.autosens)
|
||||
comparator = Comparator(mainApp, triggerAutosensValue.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val autosensData = iobCobCalculatorPlugin.getLastAutosensData("Automation trigger")
|
||||
?: return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
true
|
||||
} else {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
false
|
||||
}
|
||||
if (comparator.value.check(autosensData.autosensResult.ratio, autosens.value / 100.0)) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("value", autosens.value)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
autosens.setValue(safeGetDouble(d, "value"))
|
||||
comparator.setValue(Comparator.Compare.valueOf(safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.autosenslabel
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.autosenscompared, resourceHelper.gs(comparator.value.stringRes), autosens.value)
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.`as`)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerAutosensValue(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.autosenslabel))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.autosenslabel) + ": ", "", autosens))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
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.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerBg extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
private InputBg bg = new InputBg();
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerBg() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerBg(TriggerBg triggerBg) {
|
||||
super();
|
||||
bg = new InputBg(triggerBg.bg);
|
||||
comparator = new Comparator(triggerBg.comparator);
|
||||
lastRun = triggerBg.lastRun;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return bg.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return bg.getUnits();
|
||||
}
|
||||
|
||||
public long getLastRun() {
|
||||
return lastRun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs()) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("NOT ready for execution: " + friendlyDescription());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (glucoseStatus == null && comparator.getValue().equals(Comparator.Compare.IS_NOT_AVAILABLE)) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
if (glucoseStatus == null) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("NOT ready for execution: " + friendlyDescription());
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean doRun = comparator.getValue().check(glucoseStatus.glucose, Profile.toMgdl(bg.getValue(), bg.getUnits()));
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("NOT ready for execution: " + friendlyDescription());
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerBg.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("bg", bg.getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
data.put("units", bg.getUnits());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
bg.setUnits(JsonHelper.safeGetString(d, "units"));
|
||||
bg.setValue(JsonHelper.safeGetDouble(d, "bg"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.glucose;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
if (comparator.getValue().equals(Comparator.Compare.IS_NOT_AVAILABLE))
|
||||
return MainApp.gs(R.string.glucoseisnotavailable);
|
||||
else {
|
||||
return MainApp.gs(bg.getUnits().equals(Constants.MGDL) ? R.string.glucosecomparedmgdl : R.string.glucosecomparedmmol, MainApp.gs(comparator.getValue().getStringRes()), bg.getValue(), bg.getUnits());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.icon_cp_bgcheck);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerBg(this);
|
||||
}
|
||||
|
||||
TriggerBg setValue(double value) {
|
||||
bg.setValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBg lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBg comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBg setUnits(String units) {
|
||||
bg.setUnits(units);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.glucose))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.glucose_u, bg.getUnits()), "", bg))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.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.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import org.json.JSONObject
|
||||
|
||||
class TriggerBg(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private var bg = InputBg(mainApp)
|
||||
var comparator = Comparator(mainApp)
|
||||
|
||||
constructor(mainApp: MainApp, value : Double, units : String, compare: Comparator.Compare) : this(mainApp){
|
||||
bg = InputBg(mainApp, value, units)
|
||||
comparator = Comparator(mainApp, compare)
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, triggerBg: TriggerBg) : this(mainApp){
|
||||
bg = InputBg(mainApp, triggerBg.bg.value, triggerBg.bg.units)
|
||||
comparator = Comparator(mainApp, triggerBg.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val glucoseStatus = GlucoseStatus.getGlucoseStatusData()
|
||||
if (glucoseStatus == null && comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
if (glucoseStatus == null) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
if (comparator.value.check(glucoseStatus.glucose, Profile.toMgdl(bg.value, bg.units))) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("bg", bg.value)
|
||||
.put("comparator", comparator.value.toString())
|
||||
.put("units", bg.units)
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
bg.setUnits(JsonHelper.safeGetString(d, "units")!!)
|
||||
bg.value = JsonHelper.safeGetDouble(d, "bg")
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.glucose
|
||||
|
||||
override fun friendlyDescription(): String {
|
||||
return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
resourceHelper.gs(R.string.glucoseisnotavailable)
|
||||
else
|
||||
resourceHelper.gs(if (bg.units == Constants.MGDL) R.string.glucosecomparedmgdl else R.string.glucosecomparedmmol, resourceHelper.gs(comparator.value.stringRes), bg.value, bg.units)
|
||||
}
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.icon_cp_bgcheck)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerBg(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.glucose))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.glucose_u, bg.units), "", bg))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,150 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerBolusAgo extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
private InputDuration minutesAgo = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerBolusAgo() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerBolusAgo(TriggerBolusAgo triggerBolusAgo) {
|
||||
super();
|
||||
minutesAgo = new InputDuration(triggerBolusAgo.minutesAgo);
|
||||
lastRun = triggerBolusAgo.lastRun;
|
||||
comparator = new Comparator(triggerBolusAgo.comparator);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return minutesAgo.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
long lastBolusTime = TreatmentsPlugin.getPlugin().getLastBolusTime(false);
|
||||
|
||||
if (lastBolusTime == 0)
|
||||
if (comparator.getValue() == Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
double minutesAgo = (double) (DateUtil.now() - lastBolusTime) / (60 * 1000);
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("LastBolus min ago: " + minutesAgo);
|
||||
|
||||
boolean doRun = comparator.getValue().check((minutesAgo), getValue());
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerBolusAgo.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("minutesAgo", getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
minutesAgo.setMinutes(JsonHelper.safeGetInt(d, "minutesAgo"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.lastboluslabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.lastboluscompared, MainApp.gs(comparator.getValue().getStringRes()), (int) getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.icon_bolus);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerBolusAgo(this);
|
||||
}
|
||||
|
||||
TriggerBolusAgo setValue(int requestedValue) {
|
||||
this.minutesAgo.setMinutes(requestedValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBolusAgo lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBolusAgo comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.lastboluslabel))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.lastboluslabel) + ": ", "", minutesAgo))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration
|
||||
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.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||
import org.json.JSONObject
|
||||
|
||||
class TriggerBolusAgo(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private var minutesAgo: InputDuration = InputDuration(mainApp, 0, InputDuration.TimeUnit.MINUTES)
|
||||
var comparator: Comparator = Comparator(mainApp)
|
||||
|
||||
private constructor(mainApp: MainApp, triggerBolusAgo: TriggerBolusAgo) : this(mainApp) {
|
||||
minutesAgo = InputDuration(mainApp, triggerBolusAgo.minutesAgo.value, InputDuration.TimeUnit.MINUTES)
|
||||
comparator = Comparator(mainApp, triggerBolusAgo.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val lastBolusTime = treatmentsPlugin.getLastBolusTime(false)
|
||||
if (lastBolusTime == 0L)
|
||||
return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
true
|
||||
} else {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
false
|
||||
}
|
||||
val last = (DateUtil.now() - lastBolusTime).toDouble() / (60 * 1000)
|
||||
aapsLogger.debug(LTag.AUTOMATION, "LastBolus min ago: $minutesAgo")
|
||||
val doRun = comparator.value.check(last.toInt(), minutesAgo.getMinutes())
|
||||
if (doRun) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("minutesAgo", minutesAgo.value)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
minutesAgo.setMinutes(JsonHelper.safeGetInt(d, "minutesAgo"))
|
||||
comparator.setValue(Comparator.Compare.valueOf(safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.lastboluslabel
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.lastboluscompared, resourceHelper.gs(comparator.value.stringRes), minutesAgo.getMinutes())
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.icon_bolus)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerBolusAgo(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.lastboluslabel))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.lastboluslabel) + ": ", "", minutesAgo))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.SP;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerCOB extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
private final int minValue = 0;
|
||||
private final int maxValue = SP.getInt(R.string.key_treatmentssafety_maxcarbs, 48);
|
||||
private InputDouble value = new InputDouble(0, (double) minValue, (double) maxValue, 1, new DecimalFormat("1"));
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerCOB() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerCOB(TriggerCOB triggerCOB) {
|
||||
super();
|
||||
value = new InputDouble(triggerCOB.value);
|
||||
lastRun = triggerCOB.lastRun;
|
||||
comparator = new Comparator(triggerCOB.comparator);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return value.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
CobInfo cobInfo = IobCobCalculatorPlugin.getPlugin().getCobInfo(false, "AutomationTriggerCOB");
|
||||
if (cobInfo == null)
|
||||
if (comparator.getValue() == Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
boolean doRun = comparator.getValue().check((cobInfo.displayCob), getValue());
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerCOB.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("carbs", getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
value.setValue(JsonHelper.safeGetDouble(d, "carbs"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.triggercoblabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.cobcompared, MainApp.gs(comparator.getValue().getStringRes()), getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.icon_cp_bolus_carbs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerCOB(this);
|
||||
}
|
||||
|
||||
TriggerCOB setValue(int requestedValue) {
|
||||
this.value.setValue(requestedValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerCOB lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerCOB comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.triggercoblabel))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.triggercoblabel) + ": ", "", value))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble
|
||||
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 info.nightscout.androidaps.utils.JsonHelper.safeGetDouble
|
||||
import org.json.JSONObject
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class TriggerCOB(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private val minValue = 0
|
||||
private val maxValue = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48)
|
||||
private var cob: InputDouble = InputDouble(mainApp, 0.0, minValue.toDouble(), maxValue.toDouble(), 1.0, DecimalFormat("1"))
|
||||
var comparator: Comparator = Comparator(mainApp)
|
||||
|
||||
private constructor(mainApp: MainApp, triggerCOB: TriggerCOB) : this(mainApp) {
|
||||
cob = InputDouble(mainApp, triggerCOB.cob)
|
||||
comparator = Comparator(mainApp, triggerCOB.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val cobInfo = iobCobCalculatorPlugin.getCobInfo(false, "AutomationTriggerCOB")
|
||||
if (cobInfo.displayCob == null) {
|
||||
return if (comparator.value === Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
true
|
||||
} else {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
false
|
||||
}
|
||||
}
|
||||
if (comparator.value.check(cobInfo.displayCob, cob.value)) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
@Synchronized override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("carbs", cob.value)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
cob.setValue(safeGetDouble(d, "carbs"))
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.triggercoblabel
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.cobcompared, resourceHelper.gs(comparator.value.stringRes), cob.value)
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.icon_cp_bolus_carbs)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerCOB(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.triggercoblabel))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.triggercoblabel) + ": ", "", cob))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,277 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.TriggerListAdapter;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
|
||||
public class TriggerConnector extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
public enum Type {
|
||||
AND,
|
||||
OR,
|
||||
XOR;
|
||||
|
||||
public boolean apply(boolean a, boolean b) {
|
||||
switch (this) {
|
||||
case AND:
|
||||
return a && b;
|
||||
case OR:
|
||||
return a || b;
|
||||
case XOR:
|
||||
return a ^ b;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public @StringRes
|
||||
int getStringRes() {
|
||||
switch (this) {
|
||||
case OR:
|
||||
return R.string.or;
|
||||
case XOR:
|
||||
return R.string.xor;
|
||||
|
||||
default:
|
||||
case AND:
|
||||
return R.string.and;
|
||||
}
|
||||
}
|
||||
|
||||
public static List<String> labels() {
|
||||
List<String> list = new ArrayList<>();
|
||||
for (Type t : values()) {
|
||||
list.add(MainApp.gs(t.getStringRes()));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public static void fillIconSet(TriggerConnector connector, HashSet<Integer> set) {
|
||||
for (Trigger t : connector.list) {
|
||||
if (t instanceof TriggerConnector) {
|
||||
fillIconSet((TriggerConnector) t, set);
|
||||
} else {
|
||||
Optional<Integer> icon = t.icon();
|
||||
if (icon.isPresent()) {
|
||||
set.add(icon.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected List<Trigger> list = new ArrayList<>();
|
||||
private Type connectorType;
|
||||
|
||||
public TriggerConnector() {
|
||||
connectorType = Type.AND;
|
||||
}
|
||||
|
||||
public TriggerConnector(Type connectorType) {
|
||||
this.connectorType = connectorType;
|
||||
}
|
||||
|
||||
public void changeConnectorType(Type type) {
|
||||
this.connectorType = type;
|
||||
}
|
||||
|
||||
public Type getConnectorType() {
|
||||
return connectorType;
|
||||
}
|
||||
|
||||
public synchronized void add(Trigger t) {
|
||||
list.add(t);
|
||||
t.connector = this;
|
||||
}
|
||||
|
||||
public synchronized void add(int pos, Trigger t) {
|
||||
list.add(pos, t);
|
||||
t.connector = this;
|
||||
}
|
||||
|
||||
public synchronized boolean remove(Trigger t) {
|
||||
return list.remove(t);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
public Trigger get(int i) {
|
||||
return list.get(i);
|
||||
}
|
||||
|
||||
public int pos(Trigger trigger) {
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
if (list.get(i) == trigger) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
boolean result = true;
|
||||
|
||||
// check first trigger
|
||||
if (list.size() > 0)
|
||||
result = list.get(0).shouldRun();
|
||||
|
||||
// check all others
|
||||
for (int i = 1; i < list.size(); ++i) {
|
||||
result = connectorType.apply(result, list.get(i).shouldRun());
|
||||
}
|
||||
if (result)
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription().replace("\n", " "));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerConnector.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("connectorType", connectorType.toString());
|
||||
JSONArray array = new JSONArray();
|
||||
for (Trigger t : list) {
|
||||
array.put(t.toJSON());
|
||||
}
|
||||
data.put("triggerList", array);
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
connectorType = Type.valueOf(JsonHelper.safeGetString(d, "connectorType"));
|
||||
JSONArray array = d.getJSONArray("triggerList");
|
||||
list.clear();
|
||||
for (int i = 0; i < array.length(); i++) {
|
||||
Trigger newItem = instantiate(new JSONObject(array.getString(i)));
|
||||
add(newItem);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return connectorType.getStringRes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
int counter = 0;
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (Trigger t : list) {
|
||||
if (counter++ > 0) result.append("\n").append(MainApp.gs(friendlyName())).append("\n");
|
||||
result.append(t.friendlyDescription());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.absent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executed(long time) {
|
||||
for (int i = 0; i < list.size(); ++i) {
|
||||
list.get(i).executed(time);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private TriggerListAdapter adapter;
|
||||
|
||||
public void rebuildView(FragmentManager fragmentManager) {
|
||||
if (adapter != null)
|
||||
adapter.rebuild(fragmentManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
final int padding = MainApp.dpToPx(5);
|
||||
|
||||
root.setPadding(padding, padding, padding, padding);
|
||||
root.setBackgroundResource(R.drawable.border_automation_unit);
|
||||
|
||||
LinearLayout triggerListLayout = new LinearLayout(root.getContext());
|
||||
triggerListLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
triggerListLayout.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
root.addView(triggerListLayout);
|
||||
|
||||
adapter = new TriggerListAdapter(fragmentManager, root.getContext(), triggerListLayout, this);
|
||||
}
|
||||
|
||||
public TriggerConnector simplify() {
|
||||
// simplify children
|
||||
for (int i = 0; i < size(); ++i) {
|
||||
if (get(i) instanceof TriggerConnector) {
|
||||
TriggerConnector t = (TriggerConnector) get(i);
|
||||
t.simplify();
|
||||
}
|
||||
}
|
||||
|
||||
// drop connector with only 1 element
|
||||
if (size() == 1 && get(0) instanceof TriggerConnector) {
|
||||
TriggerConnector c = (TriggerConnector) get(0);
|
||||
remove(c);
|
||||
changeConnectorType(c.getConnectorType());
|
||||
for (Trigger t : c.list) {
|
||||
add(t);
|
||||
}
|
||||
c.list.clear();
|
||||
return simplify();
|
||||
}
|
||||
|
||||
// merge connectors
|
||||
if (connector != null && (connector.getConnectorType().equals(connectorType) || size() == 1)) {
|
||||
final int pos = connector.pos(this);
|
||||
connector.remove(this);
|
||||
// move triggers of child connector into parent connector
|
||||
for (int i = size() - 1; i >= 0; --i) {
|
||||
connector.add(pos, get(i));
|
||||
}
|
||||
list.clear();
|
||||
return connector.simplify();
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.dialogs.TriggerListAdapter
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
class TriggerConnector(mainApp: MainApp) : Trigger(mainApp) {
|
||||
var list: MutableList<Trigger> = ArrayList()
|
||||
var connectorType: Type = Type.AND
|
||||
|
||||
enum class Type {
|
||||
AND, OR, XOR;
|
||||
|
||||
fun apply(a: Boolean, b: Boolean): Boolean =
|
||||
when (this) {
|
||||
AND -> a && b
|
||||
OR -> a || b
|
||||
XOR -> a xor b
|
||||
}
|
||||
|
||||
@get:StringRes val stringRes: Int
|
||||
get() = when (this) {
|
||||
OR -> R.string.or
|
||||
XOR -> R.string.xor
|
||||
AND -> R.string.and
|
||||
}
|
||||
|
||||
fun labels(resourceHelper: ResourceHelper): List<String> {
|
||||
val list: MutableList<String> = ArrayList()
|
||||
for (t in values()) {
|
||||
list.add(resourceHelper.gs(t.stringRes))
|
||||
}
|
||||
return list
|
||||
}
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, connectorType: Type) : this(mainApp) {
|
||||
this.connectorType = connectorType
|
||||
}
|
||||
|
||||
fun setType(type: Type) {
|
||||
connectorType = type
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun add(t: Trigger) {
|
||||
list.add(t)
|
||||
t.connector = this
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun add(pos: Int, t: Trigger) {
|
||||
list.add(pos, t)
|
||||
t.connector = this
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun remove(t: Trigger): Boolean = list.remove(t)
|
||||
|
||||
fun size(): Int = list.size
|
||||
|
||||
operator fun get(i: Int): Trigger = list[i]
|
||||
|
||||
fun pos(trigger: Trigger): Int {
|
||||
for (i in list.indices) {
|
||||
if (list[i] === trigger) return i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
@Synchronized override fun shouldRun(): Boolean {
|
||||
var result = true
|
||||
// check first trigger
|
||||
if (list.size > 0) result = list[0].shouldRun()
|
||||
// check all others
|
||||
for (i in 1 until list.size) {
|
||||
result = connectorType.apply(result, list[i].shouldRun())
|
||||
}
|
||||
if (result) aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription().replace("\n", " "))
|
||||
return result
|
||||
}
|
||||
|
||||
@Synchronized override fun toJSON(): String {
|
||||
val array = JSONArray()
|
||||
for (t in list) array.put(t.toJSON())
|
||||
val data = JSONObject()
|
||||
.put("connectorType", connectorType.toString())
|
||||
.put("triggerList", array)
|
||||
return JSONObject()
|
||||
.put("type", TriggerConnector::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
connectorType = Type.valueOf(safeGetString(d, "connectorType")!!)
|
||||
val array = d.getJSONArray("triggerList")
|
||||
list.clear()
|
||||
for (i in 0 until array.length()) {
|
||||
instantiate(JSONObject(array.getString(i)))?.let {
|
||||
add(it)
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = connectorType.stringRes
|
||||
|
||||
override fun friendlyDescription(): String {
|
||||
val result = StringBuilder()
|
||||
for ((counter, t) in list.withIndex()) {
|
||||
if (counter > 0)
|
||||
result.append("\n").append(resourceHelper.gs(friendlyName())).append("\n")
|
||||
result.append(t.friendlyDescription())
|
||||
}
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.absent()
|
||||
|
||||
override fun duplicate(): Trigger = TriggerConnector(mainApp, connectorType)
|
||||
|
||||
private var adapter: TriggerListAdapter? = null
|
||||
|
||||
fun rebuildView(fragmentManager: FragmentManager) = adapter?.rebuild(fragmentManager)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
val padding = resourceHelper.dpToPx(5)
|
||||
root.setPadding(padding, padding, padding, padding)
|
||||
root.setBackgroundResource(R.drawable.border_automation_unit)
|
||||
val triggerListLayout = LinearLayout(root.context)
|
||||
triggerListLayout.orientation = LinearLayout.VERTICAL
|
||||
triggerListLayout.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
root.addView(triggerListLayout)
|
||||
adapter = TriggerListAdapter(mainApp, resourceHelper, root.context, triggerListLayout, this)
|
||||
}
|
||||
|
||||
fun simplify(): TriggerConnector { // simplify children
|
||||
for (i in 0 until size()) {
|
||||
if (get(i) is TriggerConnector) {
|
||||
val t = get(i) as TriggerConnector
|
||||
t.simplify()
|
||||
}
|
||||
}
|
||||
// drop connector with only 1 element
|
||||
if (size() == 1 && get(0) is TriggerConnector) {
|
||||
val c = get(0) as TriggerConnector
|
||||
remove(c)
|
||||
connectorType = c.connectorType
|
||||
for (t in c.list) add(t)
|
||||
c.list.clear()
|
||||
return simplify()
|
||||
}
|
||||
// merge connectors
|
||||
connector?.let { connector ->
|
||||
if (connector.connectorType == connectorType || size() == 1) {
|
||||
val pos = connector.pos(this)
|
||||
connector.remove(this)
|
||||
// move triggers of child connector into parent connector
|
||||
for (i in size() - 1 downTo 0) {
|
||||
connector.add(pos, get(i))
|
||||
}
|
||||
list.clear()
|
||||
return connector.simplify()
|
||||
}
|
||||
}
|
||||
return this
|
||||
}
|
||||
}
|
|
@ -1,202 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta.DeltaType;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerDelta extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
private final int MMOL_MAX = 4;
|
||||
private final int MGDL_MAX = 72;
|
||||
|
||||
private String units;
|
||||
private DeltaType deltaType;
|
||||
|
||||
private InputDelta value;
|
||||
private Comparator comparator;
|
||||
|
||||
public TriggerDelta() {
|
||||
super();
|
||||
this.units = ProfileFunctions.getSystemUnits();
|
||||
initializer();
|
||||
}
|
||||
|
||||
private TriggerDelta(TriggerDelta triggerDelta) {
|
||||
super();
|
||||
lastRun = triggerDelta.lastRun;
|
||||
this.units = triggerDelta.units;
|
||||
deltaType = triggerDelta.deltaType;
|
||||
value = new InputDelta(triggerDelta.value);
|
||||
comparator = new Comparator(triggerDelta.comparator);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
deltaType = value.getDeltaType();
|
||||
return value.getValue();
|
||||
}
|
||||
|
||||
private void initializer() {
|
||||
this.deltaType = DeltaType.DELTA;
|
||||
comparator = new Comparator();
|
||||
if (units.equals(Constants.MMOL))
|
||||
value = new InputDelta(0, -MMOL_MAX, MMOL_MAX, 0.1d, new DecimalFormat("0.1"), DeltaType.DELTA);
|
||||
else
|
||||
value = new InputDelta(0, -MGDL_MAX, MGDL_MAX, 1d, new DecimalFormat("1"), DeltaType.DELTA);
|
||||
}
|
||||
|
||||
|
||||
public DeltaType getType() {
|
||||
return deltaType;
|
||||
}
|
||||
|
||||
public String getUnits() {
|
||||
return this.units;
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
if (glucoseStatus == null)
|
||||
if (comparator.getValue() == Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
// Setting type of delta
|
||||
double delta;
|
||||
|
||||
if (deltaType == DeltaType.SHORT_AVERAGE)
|
||||
delta = glucoseStatus.short_avgdelta;
|
||||
else if (deltaType == DeltaType.LONG_AVERAGE)
|
||||
delta = glucoseStatus.long_avgdelta;
|
||||
else
|
||||
delta = glucoseStatus.delta;
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
boolean doRun = comparator.getValue().check(delta, Profile.toMgdl(value.getValue(), this.units));
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: delta is " + delta + " " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerDelta.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("value", getValue());
|
||||
data.put("units", units);
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("deltaType", getType());
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
units = JsonHelper.safeGetString(d, "units");
|
||||
deltaType = DeltaType.valueOf(JsonHelper.safeGetString(d, "deltaType", ""));
|
||||
value.setValue(JsonHelper.safeGetDouble(d, "value"), deltaType);
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.deltalabel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.deltacompared, MainApp.gs(comparator.getValue().getStringRes()), getValue(), MainApp.gs(deltaType.getStringRes()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.icon_auto_delta);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerDelta(this);
|
||||
}
|
||||
|
||||
TriggerDelta setValue(double requestedValue, DeltaType requestedType) {
|
||||
this.value.setValue(requestedValue, requestedType);
|
||||
this.deltaType = requestedType;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerDelta setUnits(String units) {
|
||||
this.units = units;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerDelta lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerDelta comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.deltalabel))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.deltalabel_u, getUnits()) + ": ", "", value))
|
||||
.build(root);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta.DeltaType
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import org.json.JSONObject
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class TriggerDelta(mainApp: MainApp) : Trigger(mainApp) {
|
||||
|
||||
var units: String = Constants.MGDL
|
||||
private var delta: InputDelta = InputDelta(mainApp)
|
||||
var comparator: Comparator = Comparator(mainApp)
|
||||
|
||||
companion object {
|
||||
private const val MMOL_MAX = 4.0
|
||||
private const val MGDL_MAX = 72.0
|
||||
}
|
||||
|
||||
init {
|
||||
units = profileFunction.getUnits()
|
||||
delta = if (units == Constants.MMOL) InputDelta(mainApp, 0.0, (-MMOL_MAX), MMOL_MAX, 0.1, DecimalFormat("0.1"), DeltaType.DELTA)
|
||||
else InputDelta(mainApp, 0.0, (-MGDL_MAX), MGDL_MAX, 1.0, DecimalFormat("1"), DeltaType.DELTA)
|
||||
}
|
||||
|
||||
private constructor(mainApp: MainApp, triggerDelta: TriggerDelta) : this(mainApp) {
|
||||
units = triggerDelta.units
|
||||
delta = InputDelta(mainApp, triggerDelta.delta)
|
||||
comparator = Comparator(mainApp, triggerDelta.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val glucoseStatus = GlucoseStatus.getGlucoseStatusData()
|
||||
?: return if (comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
true
|
||||
} else {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
false
|
||||
}
|
||||
val calculatedDelta = when (delta.deltaType) {
|
||||
DeltaType.SHORT_AVERAGE -> glucoseStatus.short_avgdelta
|
||||
DeltaType.LONG_AVERAGE -> glucoseStatus.long_avgdelta
|
||||
else -> glucoseStatus.delta
|
||||
}
|
||||
if (comparator.value.check(calculatedDelta, Profile.toMgdl(delta.value, units))) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: delta is " + calculatedDelta + " " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("value", delta.value)
|
||||
.put("units", units)
|
||||
.put("deltaType", delta.deltaType)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
units = JsonHelper.safeGetString(d, "units")!!
|
||||
val type = DeltaType.valueOf(JsonHelper.safeGetString(d, "deltaType", ""))
|
||||
val value = JsonHelper.safeGetDouble(d, "value")
|
||||
delta =
|
||||
if (units == Constants.MMOL) InputDelta(mainApp, value, (-MMOL_MAX), MMOL_MAX, 0.1, DecimalFormat("0.1"), type)
|
||||
else InputDelta(mainApp, value, (-MGDL_MAX), MGDL_MAX, 1.0, DecimalFormat("1"), type)
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.deltalabel
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.deltacompared, resourceHelper.gs(comparator.value.stringRes), delta.value, resourceHelper.gs(delta.deltaType.stringRes))
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.icon_auto_delta)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerDelta(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.deltalabel))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.deltalabel_u, units) + ": ", "", delta))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
|
||||
// Used for instantiation of other triggers only
|
||||
class TriggerDummy(mainApp: MainApp) : Trigger(mainApp) {
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
throw NotImplementedError("An operation is not implemented")
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
throw NotImplementedError("An operation is not implemented")
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
throw NotImplementedError("An operation is not implemented")
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int {
|
||||
throw NotImplementedError("An operation is not implemented")
|
||||
}
|
||||
|
||||
override fun friendlyDescription(): String {
|
||||
throw NotImplementedError("An operation is not implemented")
|
||||
}
|
||||
|
||||
override fun icon(): Optional<Int?> {
|
||||
throw NotImplementedError("An operation is not implemented")
|
||||
}
|
||||
|
||||
override fun duplicate(): Trigger {
|
||||
throw NotImplementedError("An operation is not implemented")
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputInsulin;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerIob extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
private InputInsulin insulin = new InputInsulin();
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerIob() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerIob(TriggerIob triggerIob) {
|
||||
super();
|
||||
insulin = new InputInsulin(triggerIob.insulin);
|
||||
comparator = new Comparator(triggerIob.comparator);
|
||||
lastRun = triggerIob.lastRun;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return insulin.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile == null)
|
||||
return false;
|
||||
IobTotal iob = IobCobCalculatorPlugin.getPlugin().calculateFromTreatmentsAndTempsSynchronized(DateUtil.now(), profile);
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
boolean doRun = comparator.getValue().check(iob.iob, getValue());
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerIob.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("insulin", getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
insulin.setValue(JsonHelper.safeGetDouble(d, "insulin"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.iob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.iobcompared, MainApp.gs(comparator.getValue().getStringRes()), getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.ic_keyboard_capslock);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerIob(this);
|
||||
}
|
||||
|
||||
TriggerIob setValue(double threshold) {
|
||||
insulin.setValue(threshold);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerIob lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerIob comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.iob))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.iob_u), "", insulin))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputInsulin
|
||||
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.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import org.json.JSONObject
|
||||
|
||||
class TriggerIob(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private var insulin = InputInsulin(mainApp)
|
||||
var comparator: Comparator = Comparator(mainApp)
|
||||
|
||||
constructor(mainApp: MainApp, triggerIob: TriggerIob) : this(mainApp) {
|
||||
insulin = InputInsulin(mainApp, triggerIob.insulin)
|
||||
comparator = Comparator(mainApp, triggerIob.comparator.value)
|
||||
}
|
||||
|
||||
val value: Double = 0.0
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val profile = profileFunction.getProfile() ?: return false
|
||||
val iob = iobCobCalculatorPlugin.calculateFromTreatmentsAndTempsSynchronized(DateUtil.now(), profile)
|
||||
if (comparator.value.check(iob.iob, value)) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
@Synchronized override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("insulin", value)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
insulin.value = JsonHelper.safeGetDouble(d, "insulin")
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.iob
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.iobcompared, resourceHelper.gs(comparator.value.stringRes), value)
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_keyboard_capslock)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerIob(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.iob))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.iob_u), "", insulin))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,190 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.location.Location;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputButton;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDouble;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputLocationMode;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputString;
|
||||
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.services.LocationService;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
import static info.nightscout.androidaps.plugins.general.automation.elements.InputLocationMode.Mode.*;
|
||||
|
||||
public class TriggerLocation extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
InputDouble latitude = new InputDouble(0d, -90d, +90d, 0.000001d, new DecimalFormat("0.000000"));
|
||||
InputDouble longitude = new InputDouble(0d, -180d, +180d, 0.000001d, new DecimalFormat("0.000000"));
|
||||
InputDouble distance = new InputDouble(200d, 0, 100000, 10d, new DecimalFormat("0"));
|
||||
InputLocationMode modeSelected = new InputLocationMode();
|
||||
InputLocationMode.Mode lastMode = INSIDE;
|
||||
|
||||
InputString name = new InputString();
|
||||
|
||||
private Runnable buttonAction = () -> {
|
||||
Location location = LocationService.getLastLocation();
|
||||
if (location != null) {
|
||||
latitude.setValue(location.getLatitude());
|
||||
longitude.setValue(location.getLongitude());
|
||||
log.debug(String.format("Grabbed location: %f %f", latitude.getValue(), longitude.getValue()));
|
||||
}
|
||||
};
|
||||
|
||||
public TriggerLocation() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerLocation(TriggerLocation triggerLocation) {
|
||||
super();
|
||||
latitude = new InputDouble(triggerLocation.latitude);
|
||||
longitude = new InputDouble(triggerLocation.longitude);
|
||||
distance = new InputDouble(triggerLocation.distance);
|
||||
modeSelected = new InputLocationMode(triggerLocation.modeSelected);
|
||||
if (modeSelected.getValue() == GOING_OUT)
|
||||
lastMode = OUTSIDE;
|
||||
lastRun = triggerLocation.lastRun;
|
||||
name = triggerLocation.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
Location location = this.getCurrentLocation();
|
||||
if (location == null)
|
||||
return false;
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
Location a = new Location("Trigger");
|
||||
a.setLatitude(latitude.getValue());
|
||||
a.setLongitude(longitude.getValue());
|
||||
double calculatedDistance = location.distanceTo(a);
|
||||
|
||||
// log.debug("Moded(current/last/wanted): "+(currentMode(calculatedDistance))+"/"+lastMode+"/"+modeSelected.getValue());
|
||||
// log.debug("Distance: "+calculatedDistance + "("+distance.getValue()+")");
|
||||
|
||||
if ((modeSelected.getValue() == INSIDE) && (calculatedDistance <= distance.getValue()) ||
|
||||
((modeSelected.getValue() == OUTSIDE) && (calculatedDistance > distance.getValue())) ||
|
||||
((modeSelected.getValue() == GOING_IN) && (calculatedDistance <= distance.getValue()) && (lastMode == OUTSIDE)) ||
|
||||
((modeSelected.getValue() == GOING_OUT) && (calculatedDistance > distance.getValue()) && (lastMode == INSIDE))
|
||||
) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
lastMode = currentMode(calculatedDistance);
|
||||
return true;
|
||||
}
|
||||
lastMode = currentMode(calculatedDistance); // current mode will be last mode for the next check
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerLocation.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("latitude", latitude.getValue());
|
||||
data.put("longitude", longitude.getValue());
|
||||
data.put("distance", distance.getValue());
|
||||
data.put("name", name.getValue());
|
||||
data.put("mode", modeSelected.getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
latitude.setValue(JsonHelper.safeGetDouble(d, "latitude"));
|
||||
longitude.setValue(JsonHelper.safeGetDouble(d, "longitude"));
|
||||
distance.setValue(JsonHelper.safeGetDouble(d, "distance"));
|
||||
name.setValue(JsonHelper.safeGetString(d, "name"));
|
||||
modeSelected.setValue(InputLocationMode.Mode.valueOf(JsonHelper.safeGetString(d, "mode")));
|
||||
if (modeSelected.getValue() == GOING_OUT)
|
||||
lastMode = OUTSIDE;
|
||||
lastRun = DateUtil.now(); // set lastRun to now to give the service 5 mins to get the location properly
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.location;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.locationis, MainApp.gs(modeSelected.getValue().getStringRes()), " " + name.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.ic_location_on);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerLocation(this);
|
||||
}
|
||||
|
||||
|
||||
TriggerLocation lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.location))
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.name_short), "", name))
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.latitude_short), "", latitude))
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.longitude_short), "", longitude))
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.distance_short), "", distance))
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.location_mode), "", modeSelected))
|
||||
.add(new InputButton(MainApp.gs(R.string.currentlocation), buttonAction), LocationService.getLastLocation() != null)
|
||||
.build(root);
|
||||
}
|
||||
|
||||
// Method to return the actual mode based on the current distance
|
||||
InputLocationMode.Mode currentMode(double currentDistance){
|
||||
if ( currentDistance <= this.distance.getValue() )
|
||||
return INSIDE;
|
||||
else
|
||||
return OUTSIDE;
|
||||
}
|
||||
|
||||
// for mocking only TODO remove
|
||||
static Location getCurrentLocation(){
|
||||
return LocationService.getLastLocation();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.location.Location
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.*
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import org.json.JSONObject
|
||||
import java.text.DecimalFormat
|
||||
|
||||
class TriggerLocation(mainApp: MainApp) : Trigger(mainApp) {
|
||||
var latitude = InputDouble(mainApp, 0.0, -90.0, +90.0, 0.000001, DecimalFormat("0.000000"))
|
||||
var longitude = InputDouble(mainApp, 0.0, -180.0, +180.0, 0.000001, DecimalFormat("0.000000"))
|
||||
var distance = InputDouble(mainApp, 200.0, 0.0, 100000.0, 10.0, DecimalFormat("0"))
|
||||
var modeSelected = InputLocationMode(mainApp)
|
||||
var name: InputString = InputString(mainApp)
|
||||
|
||||
var lastMode = InputLocationMode.Mode.INSIDE
|
||||
private val buttonAction = Runnable {
|
||||
val location = locationService.lastLocation
|
||||
if (location != null) {
|
||||
latitude.value = location.latitude
|
||||
longitude.value = location.longitude
|
||||
aapsLogger.debug(LTag.AUTOMATION, String.format("Grabbed location: %f %f", latitude.value, longitude.value))
|
||||
}
|
||||
}
|
||||
|
||||
private constructor(mainApp: MainApp, triggerLocation: TriggerLocation) : this(mainApp) {
|
||||
latitude = InputDouble(mainApp, triggerLocation.latitude)
|
||||
longitude = InputDouble(mainApp, triggerLocation.longitude)
|
||||
distance = InputDouble(mainApp, triggerLocation.distance)
|
||||
modeSelected = InputLocationMode(mainApp, triggerLocation.modeSelected.value)
|
||||
if (modeSelected.value == InputLocationMode.Mode.GOING_OUT)
|
||||
lastMode = InputLocationMode.Mode.OUTSIDE
|
||||
name = triggerLocation.name
|
||||
}
|
||||
|
||||
@Synchronized override fun shouldRun(): Boolean {
|
||||
val location: Location = locationService.lastLocation ?: return false
|
||||
val a = Location("Trigger")
|
||||
a.latitude = latitude.value
|
||||
a.longitude = longitude.value
|
||||
val calculatedDistance = location.distanceTo(a).toDouble()
|
||||
if (modeSelected.value == InputLocationMode.Mode.INSIDE && calculatedDistance <= distance.value ||
|
||||
modeSelected.value == InputLocationMode.Mode.OUTSIDE && calculatedDistance > distance.value ||
|
||||
modeSelected.value == InputLocationMode.Mode.GOING_IN && calculatedDistance <= distance.value && lastMode == InputLocationMode.Mode.OUTSIDE ||
|
||||
modeSelected.value == InputLocationMode.Mode.GOING_OUT && calculatedDistance > distance.value && lastMode == InputLocationMode.Mode.INSIDE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
lastMode = currentMode(calculatedDistance)
|
||||
return true
|
||||
}
|
||||
lastMode = currentMode(calculatedDistance) // current mode will be last mode for the next check
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("latitude", latitude.value)
|
||||
.put("longitude", longitude.value)
|
||||
.put("distance", distance.value)
|
||||
.put("name", name.value)
|
||||
.put("mode", modeSelected.value)
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
latitude.value = JsonHelper.safeGetDouble(d, "latitude")
|
||||
longitude.value = JsonHelper.safeGetDouble(d, "longitude")
|
||||
distance.value = JsonHelper.safeGetDouble(d, "distance")
|
||||
name.value = JsonHelper.safeGetString(d, "name")!!
|
||||
modeSelected.value = InputLocationMode.Mode.valueOf(JsonHelper.safeGetString(d, "mode")!!)
|
||||
if (modeSelected.value == InputLocationMode.Mode.GOING_OUT) lastMode = InputLocationMode.Mode.OUTSIDE
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.location
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.locationis, resourceHelper.gs(modeSelected.value.stringRes), " " + name.value)
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_location_on)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerLocation(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.location))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.name_short), "", name))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.latitude_short), "", latitude))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.longitude_short), "", longitude))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.distance_short), "", distance))
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.location_mode), "", modeSelected))
|
||||
.add(InputButton(mainApp, resourceHelper.gs(R.string.currentlocation), buttonAction), locationService.lastLocation != null)
|
||||
.build(root)
|
||||
}
|
||||
|
||||
// Method to return the actual mode based on the current distance
|
||||
fun currentMode(currentDistance: Double): InputLocationMode.Mode {
|
||||
return if (currentDistance <= distance.value) InputLocationMode.Mode.INSIDE else InputLocationMode.Mode.OUTSIDE
|
||||
}
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputPercent;
|
||||
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.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerProfilePercent extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
private InputPercent pct = new InputPercent();
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerProfilePercent() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerProfilePercent(TriggerProfilePercent triggerProfilePercent) {
|
||||
super();
|
||||
pct = new InputPercent(triggerProfilePercent.pct);
|
||||
comparator = new Comparator(triggerProfilePercent.comparator);
|
||||
lastRun = triggerProfilePercent.lastRun;
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return pct.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
public long getLastRun() {
|
||||
return lastRun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile == null && comparator.getValue().equals(Comparator.Compare.IS_NOT_AVAILABLE)) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
if (profile == null)
|
||||
return false;
|
||||
|
||||
boolean doRun = comparator.getValue().check((double) profile.getPercentage(), pct.getValue());
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerProfilePercent.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("percentage", pct.getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
pct.setValue(JsonHelper.safeGetDouble(d, "percentage"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.profilepercentage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.percentagecompared, MainApp.gs(comparator.getValue().getStringRes()), (int) pct.getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.icon_actions_profileswitch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerProfilePercent(this);
|
||||
}
|
||||
|
||||
public TriggerProfilePercent setValue(double value) {
|
||||
pct.setValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerProfilePercent lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TriggerProfilePercent comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.profilepercentage))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.percent_u), "", pct))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputPercent
|
||||
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 TriggerProfilePercent(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private var pct = InputPercent(mainApp)
|
||||
var comparator = Comparator(mainApp)
|
||||
|
||||
constructor(mainApp: MainApp, value: Double, compare: Comparator.Compare) : this(mainApp) {
|
||||
pct = InputPercent(mainApp, value)
|
||||
comparator = Comparator(mainApp, compare)
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, triggerProfilePercent: TriggerProfilePercent) : this(mainApp) {
|
||||
pct = InputPercent(mainApp, triggerProfilePercent.pct.value)
|
||||
comparator = Comparator(mainApp, triggerProfilePercent.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val profile = profileFunction.getProfile()
|
||||
if (profile == null && comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
if (profile == null) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
if (comparator.value.check(profile.percentage.toDouble(), pct.value)) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
@Synchronized override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("percentage", pct.value)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
pct.value = JsonHelper.safeGetDouble(d, "percentage")
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.profilepercentage
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.percentagecompared, resourceHelper.gs(comparator.value.stringRes), pct.value.toInt())
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.icon_actions_profileswitch)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerProfilePercent(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.profilepercentage))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.percent_u), "", pct))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
|
||||
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.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerPumpLastConnection extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
private InputDuration minutesAgo = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerPumpLastConnection() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerPumpLastConnection(TriggerPumpLastConnection triggerPumpLastConnection) {
|
||||
super();
|
||||
minutesAgo = new InputDuration(triggerPumpLastConnection.minutesAgo);
|
||||
lastRun = triggerPumpLastConnection.lastRun;
|
||||
comparator = new Comparator(triggerPumpLastConnection.comparator);
|
||||
}
|
||||
|
||||
public double getValue() {
|
||||
return minutesAgo.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
long lastConnection = ConfigBuilderPlugin.getPlugin().getActivePump().lastDataTime();
|
||||
|
||||
if (lastConnection == 0 && comparator.getValue() == Comparator.Compare.IS_NOT_AVAILABLE)
|
||||
return true;
|
||||
|
||||
double minutesAgo = (double) (DateUtil.now() - lastConnection) / (60 * 1000);
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Last connection min ago: " + minutesAgo);
|
||||
|
||||
boolean doRun = comparator.getValue().check((minutesAgo), getValue());
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerPumpLastConnection.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("minutesAgo", getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
minutesAgo.setMinutes(JsonHelper.safeGetInt(d, "minutesAgo"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.automation_trigger_pump_last_connection_label;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.automation_trigger_pump_last_connection_compared, MainApp.gs(comparator.getValue().getStringRes()), (int) getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.remove);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerPumpLastConnection(this);
|
||||
}
|
||||
|
||||
TriggerPumpLastConnection setValue(int requestedValue) {
|
||||
this.minutesAgo.setMinutes(requestedValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerPumpLastConnection lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerPumpLastConnection comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.automation_trigger_pump_last_connection_label))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.automation_trigger_pump_last_connection_description) + ": ", "", minutesAgo))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration
|
||||
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.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
|
||||
import org.json.JSONObject
|
||||
|
||||
class TriggerPumpLastConnection(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private var minutesAgo = InputDuration(mainApp)
|
||||
private var comparator = Comparator(mainApp)
|
||||
|
||||
constructor(mainApp: MainApp, value: Int, unit: InputDuration.TimeUnit, compare: Comparator.Compare) : this(mainApp) {
|
||||
minutesAgo = InputDuration(mainApp, value, unit)
|
||||
comparator = Comparator(mainApp, compare)
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, triggerPumpLastConnection: TriggerPumpLastConnection) : this(mainApp) {
|
||||
minutesAgo = InputDuration(mainApp, triggerPumpLastConnection.minutesAgo.value, triggerPumpLastConnection.minutesAgo.unit)
|
||||
comparator = Comparator(mainApp, triggerPumpLastConnection.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val lastConnection = configBuilderPlugin.activePump?.lastDataTime() ?: return false
|
||||
if (lastConnection == 0L && comparator.value === Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
val connectionAgo = (DateUtil.now() - lastConnection) / (60 * 1000)
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Last connection min ago: $connectionAgo")
|
||||
if (comparator.value.check(connectionAgo.toInt(), minutesAgo.value)) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("minutesAgo", minutesAgo.value)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
minutesAgo.setMinutes(safeGetInt(d, "minutesAgo"))
|
||||
comparator.setValue(Comparator.Compare.valueOf(safeGetString(d, "comparator")!!))
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.automation_trigger_pump_last_connection_label
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.automation_trigger_pump_last_connection_compared, resourceHelper.gs(comparator.value.stringRes), minutesAgo.value)
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.remove)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerPumpLastConnection(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.automation_trigger_pump_last_connection_label))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.automation_trigger_pump_last_connection_description) + ": ", "", minutesAgo))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,319 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.dpro.widgets.WeekdaysPicker;
|
||||
import com.google.common.base.Optional;
|
||||
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerRecurringTime extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
public enum DayOfWeek {
|
||||
MONDAY,
|
||||
TUESDAY,
|
||||
WEDNESDAY,
|
||||
THURSDAY,
|
||||
FRIDAY,
|
||||
SATURDAY,
|
||||
SUNDAY;
|
||||
|
||||
private static final int[] calendarInts = new int[]{
|
||||
Calendar.MONDAY,
|
||||
Calendar.TUESDAY,
|
||||
Calendar.WEDNESDAY,
|
||||
Calendar.THURSDAY,
|
||||
Calendar.FRIDAY,
|
||||
Calendar.SATURDAY,
|
||||
Calendar.SUNDAY
|
||||
};
|
||||
|
||||
private static final int[] shortNames = new int[]{
|
||||
R.string.weekday_monday_short,
|
||||
R.string.weekday_tuesday_short,
|
||||
R.string.weekday_wednesday_short,
|
||||
R.string.weekday_thursday_short,
|
||||
R.string.weekday_friday_short,
|
||||
R.string.weekday_saturday_short,
|
||||
R.string.weekday_sunday_short
|
||||
};
|
||||
|
||||
public int toCalendarInt() {
|
||||
return calendarInts[ordinal()];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static DayOfWeek fromCalendarInt(int day) {
|
||||
for (int i = 0; i < calendarInts.length; ++i) {
|
||||
if (calendarInts[i] == day)
|
||||
return values()[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public @StringRes
|
||||
int getShortName() {
|
||||
return shortNames[ordinal()];
|
||||
}
|
||||
}
|
||||
|
||||
private final boolean[] weekdays = new boolean[DayOfWeek.values().length];
|
||||
|
||||
// Recurring
|
||||
private int hour;
|
||||
private int minute;
|
||||
|
||||
private long validTo;
|
||||
|
||||
public TriggerRecurringTime() {
|
||||
super();
|
||||
setAll(false);
|
||||
}
|
||||
|
||||
private TriggerRecurringTime(TriggerRecurringTime triggerTime) {
|
||||
super();
|
||||
lastRun = triggerTime.lastRun;
|
||||
hour = triggerTime.hour;
|
||||
minute = triggerTime.minute;
|
||||
validTo = triggerTime.validTo;
|
||||
|
||||
if (weekdays.length >= 0)
|
||||
System.arraycopy(triggerTime.weekdays, 0, weekdays, 0, weekdays.length);
|
||||
}
|
||||
|
||||
public void setAll(boolean value) {
|
||||
for (DayOfWeek day : DayOfWeek.values()) {
|
||||
set(day, value);
|
||||
}
|
||||
}
|
||||
|
||||
public TriggerRecurringTime set(DayOfWeek day, boolean value) {
|
||||
weekdays[day.ordinal()] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean isSet(DayOfWeek day) {
|
||||
return weekdays[day.ordinal()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRun() {
|
||||
if (validTo != 0 && DateUtil.now() > validTo)
|
||||
return false;
|
||||
Calendar c = Calendar.getInstance();
|
||||
int scheduledDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
|
||||
|
||||
Calendar scheduledCal = DateUtil.gregorianCalendar();
|
||||
scheduledCal.set(Calendar.HOUR_OF_DAY, hour);
|
||||
scheduledCal.set(Calendar.MINUTE, minute);
|
||||
scheduledCal.set(Calendar.SECOND, 0);
|
||||
long scheduled = scheduledCal.getTimeInMillis();
|
||||
|
||||
if (isSet(Objects.requireNonNull(DayOfWeek.fromCalendarInt(scheduledDayOfWeek)))) {
|
||||
if (DateUtil.now() >= scheduled && DateUtil.now() - scheduled < T.mins(5).msecs()) {
|
||||
if (lastRun < scheduled) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
data.put("lastRun", lastRun);
|
||||
for (int i = 0; i < weekdays.length; ++i) {
|
||||
data.put(DayOfWeek.values()[i].name(), weekdays[i]);
|
||||
}
|
||||
data.put("hour", hour);
|
||||
data.put("minute", minute);
|
||||
data.put("validTo", validTo);
|
||||
object.put("type", TriggerRecurringTime.class.getName());
|
||||
object.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
JSONObject o;
|
||||
try {
|
||||
o = new JSONObject(data);
|
||||
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
||||
for (int i = 0; i < weekdays.length; ++i) {
|
||||
weekdays[i] = JsonHelper.safeGetBoolean(o, DayOfWeek.values()[i].name());
|
||||
}
|
||||
hour = JsonHelper.safeGetInt(o, "hour");
|
||||
minute = JsonHelper.safeGetInt(o, "minute");
|
||||
validTo = JsonHelper.safeGetLong(o, "validTo");
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.recurringTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
int counter = 0;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(MainApp.gs(R.string.every));
|
||||
sb.append(" ");
|
||||
for (Integer i : getSelectedDays()) {
|
||||
if (counter > 0)
|
||||
sb.append(",");
|
||||
sb.append(MainApp.gs(Objects.requireNonNull(DayOfWeek.fromCalendarInt(i)).getShortName()));
|
||||
counter++;
|
||||
}
|
||||
sb.append(" ");
|
||||
|
||||
Calendar scheduledCal = DateUtil.gregorianCalendar();
|
||||
scheduledCal.set(Calendar.HOUR_OF_DAY, hour);
|
||||
scheduledCal.set(Calendar.MINUTE, minute);
|
||||
scheduledCal.set(Calendar.SECOND, 0);
|
||||
long scheduled = scheduledCal.getTimeInMillis();
|
||||
|
||||
sb.append(DateUtil.timeString(scheduled));
|
||||
|
||||
if (counter == 0)
|
||||
return MainApp.gs(R.string.never);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.ic_access_alarm_24dp);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerRecurringTime(this);
|
||||
}
|
||||
|
||||
TriggerRecurringTime lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
@SuppressWarnings("SameParameterValue")
|
||||
TriggerRecurringTime validTo(long validTo) {
|
||||
this.validTo = validTo;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerRecurringTime hour(int hour) {
|
||||
this.hour = hour;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerRecurringTime minute(int minute) {
|
||||
this.minute = minute;
|
||||
return this;
|
||||
}
|
||||
|
||||
private List<Integer> getSelectedDays() {
|
||||
List<Integer> selectedDays = new ArrayList<>();
|
||||
for (int i = 0; i < weekdays.length; ++i) {
|
||||
DayOfWeek day = DayOfWeek.values()[i];
|
||||
boolean selected = weekdays[i];
|
||||
if (selected) selectedDays.add(day.toCalendarInt());
|
||||
}
|
||||
return selectedDays;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
TextView label = new TextView(root.getContext());
|
||||
|
||||
// TODO: Replace external tool WeekdaysPicker with a self-made GUI element
|
||||
WeekdaysPicker weekdaysPicker = new WeekdaysPicker(root.getContext());
|
||||
weekdaysPicker.setEditable(true);
|
||||
weekdaysPicker.setSelectedDays(getSelectedDays());
|
||||
weekdaysPicker.setOnWeekdaysChangeListener((view, i, list) -> set(DayOfWeek.fromCalendarInt(i), list.contains(i)));
|
||||
weekdaysPicker.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
weekdaysPicker.setSundayFirstDay(Calendar.getInstance().getFirstDayOfWeek() == Calendar.SUNDAY);
|
||||
weekdaysPicker.redrawDays();
|
||||
|
||||
root.addView(weekdaysPicker);
|
||||
|
||||
TextView timeButton = new TextView(root.getContext());
|
||||
|
||||
GregorianCalendar runAt = new GregorianCalendar();
|
||||
//Date runAt = new Date();
|
||||
runAt.set(Calendar.HOUR_OF_DAY, hour);
|
||||
runAt.set(Calendar.MINUTE, minute);
|
||||
timeButton.setText(DateUtil.timeString(runAt.getTimeInMillis()));
|
||||
timeButton.setOnClickListener(view -> {
|
||||
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||
(view12, hourOfDay, minute, second) -> {
|
||||
hour(hourOfDay);
|
||||
minute(minute);
|
||||
runAt.set(Calendar.HOUR_OF_DAY, hour);
|
||||
runAt.set(Calendar.MINUTE, minute);
|
||||
timeButton.setText(DateUtil.timeString(runAt.getTimeInMillis()));
|
||||
},
|
||||
runAt.get(Calendar.HOUR_OF_DAY),
|
||||
runAt.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(root.getContext())
|
||||
);
|
||||
tpd.setThemeDark(true);
|
||||
tpd.dismissOnPause(true);
|
||||
AppCompatActivity a = scanForActivity(root.getContext());
|
||||
if (a != null)
|
||||
tpd.show(a.getSupportFragmentManager(), "TimePickerDialog");
|
||||
});
|
||||
|
||||
int px = MainApp.dpToPx(10);
|
||||
label.setText(MainApp.gs(R.string.atspecifiedtime, ""));
|
||||
label.setTypeface(label.getTypeface(), Typeface.BOLD);
|
||||
label.setPadding(px, px, px, px);
|
||||
timeButton.setPadding(px, px, px, px);
|
||||
|
||||
LinearLayout l = new LinearLayout(root.getContext());
|
||||
l.setOrientation(LinearLayout.HORIZONTAL);
|
||||
l.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
l.addView(label);
|
||||
l.addView(timeButton);
|
||||
root.addView(l);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,211 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.app.TimePickerDialog
|
||||
import android.graphics.Typeface
|
||||
import android.text.format.DateFormat
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.annotation.StringRes
|
||||
import com.dpro.widgets.WeekdaysPicker
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
class TriggerRecurringTime(mainApp: MainApp) : Trigger(mainApp) {
|
||||
enum class DayOfWeek {
|
||||
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
|
||||
|
||||
fun toCalendarInt(): Int {
|
||||
return calendarInts[ordinal]
|
||||
}
|
||||
|
||||
@get:StringRes val shortName: Int
|
||||
get() = shortNames[ordinal]
|
||||
|
||||
companion object {
|
||||
private val calendarInts = intArrayOf(
|
||||
Calendar.MONDAY,
|
||||
Calendar.TUESDAY,
|
||||
Calendar.WEDNESDAY,
|
||||
Calendar.THURSDAY,
|
||||
Calendar.FRIDAY,
|
||||
Calendar.SATURDAY,
|
||||
Calendar.SUNDAY
|
||||
)
|
||||
private val shortNames = intArrayOf(
|
||||
R.string.weekday_monday_short,
|
||||
R.string.weekday_tuesday_short,
|
||||
R.string.weekday_wednesday_short,
|
||||
R.string.weekday_thursday_short,
|
||||
R.string.weekday_friday_short,
|
||||
R.string.weekday_saturday_short,
|
||||
R.string.weekday_sunday_short
|
||||
)
|
||||
|
||||
fun fromCalendarInt(day: Int): DayOfWeek {
|
||||
for (i in calendarInts.indices) {
|
||||
if (calendarInts[i] == day) return values()[i]
|
||||
}
|
||||
throw IllegalStateException("Invalid day")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val weekdays = BooleanArray(DayOfWeek.values().size)
|
||||
private var hour = 0
|
||||
private var minute = 0
|
||||
private var validTo: Long = 0
|
||||
|
||||
constructor(mainApp: MainApp, triggerRecurringTime: TriggerRecurringTime) : this(mainApp) {
|
||||
this.hour = triggerRecurringTime.hour
|
||||
this.minute = triggerRecurringTime.minute
|
||||
this.validTo = triggerRecurringTime.validTo
|
||||
if (weekdays.size >= 0)
|
||||
System.arraycopy(triggerRecurringTime.weekdays, 0, weekdays, 0, triggerRecurringTime.weekdays.size)
|
||||
}
|
||||
|
||||
init {
|
||||
for (day in DayOfWeek.values()) set(day, false)
|
||||
}
|
||||
|
||||
operator fun set(day: DayOfWeek, value: Boolean): TriggerRecurringTime {
|
||||
weekdays[day.ordinal] = value
|
||||
return this
|
||||
}
|
||||
|
||||
private fun isSet(day: DayOfWeek): Boolean = weekdays[day.ordinal]
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
if (validTo != 0L && DateUtil.now() > validTo) return false
|
||||
val c = Calendar.getInstance()
|
||||
val scheduledDayOfWeek = c[Calendar.DAY_OF_WEEK]
|
||||
val scheduledCal: Calendar = DateUtil.gregorianCalendar()
|
||||
scheduledCal[Calendar.HOUR_OF_DAY] = hour
|
||||
scheduledCal[Calendar.MINUTE] = minute
|
||||
scheduledCal[Calendar.SECOND] = 0
|
||||
val scheduled = scheduledCal.timeInMillis
|
||||
if (isSet(Objects.requireNonNull(DayOfWeek.fromCalendarInt(scheduledDayOfWeek)))) {
|
||||
if (DateUtil.now() >= scheduled && DateUtil.now() - scheduled < T.mins(5).msecs()) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("hour", hour)
|
||||
.put("minute", minute)
|
||||
.put("validTo", validTo)
|
||||
for (i in weekdays.indices) {
|
||||
data.put(DayOfWeek.values()[i].name, weekdays[i])
|
||||
}
|
||||
return JSONObject()
|
||||
.put("type", TriggerRecurringTime::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val o = JSONObject(data)
|
||||
for (i in weekdays.indices)
|
||||
weekdays[i] = JsonHelper.safeGetBoolean(o, DayOfWeek.values()[i].name)
|
||||
hour = JsonHelper.safeGetInt(o, "hour")
|
||||
minute = JsonHelper.safeGetInt(o, "minute")
|
||||
validTo = JsonHelper.safeGetLong(o, "validTo")
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.recurringTime
|
||||
|
||||
override fun friendlyDescription(): String {
|
||||
val sb = StringBuilder()
|
||||
sb.append(resourceHelper.gs(R.string.every))
|
||||
sb.append(" ")
|
||||
var counter = 0
|
||||
for (i in getSelectedDays()) {
|
||||
if (counter++ > 0) sb.append(",")
|
||||
sb.append(resourceHelper.gs(Objects.requireNonNull(DayOfWeek.fromCalendarInt(i)).shortName))
|
||||
}
|
||||
sb.append(" ")
|
||||
val scheduledCal: Calendar = DateUtil.gregorianCalendar()
|
||||
scheduledCal[Calendar.HOUR_OF_DAY] = hour
|
||||
scheduledCal[Calendar.MINUTE] = minute
|
||||
scheduledCal[Calendar.SECOND] = 0
|
||||
val scheduled = scheduledCal.timeInMillis
|
||||
sb.append(DateUtil.timeString(scheduled))
|
||||
return if (counter == 0) resourceHelper.gs(R.string.never) else sb.toString()
|
||||
}
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_access_alarm_24dp)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerRecurringTime(mainApp, this)
|
||||
|
||||
private fun getSelectedDays(): List<Int> {
|
||||
val selectedDays: MutableList<Int> = ArrayList()
|
||||
for (i in weekdays.indices) {
|
||||
val day = DayOfWeek.values()[i]
|
||||
val selected = weekdays[i]
|
||||
if (selected) selectedDays.add(day.toCalendarInt())
|
||||
}
|
||||
return selectedDays
|
||||
}
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
val label = TextView(root.context)
|
||||
// TODO: Replace external tool WeekdaysPicker with a self-made GUI element
|
||||
val weekdaysPicker = WeekdaysPicker(root.context)
|
||||
weekdaysPicker.setEditable(true)
|
||||
weekdaysPicker.selectedDays = getSelectedDays()
|
||||
weekdaysPicker.setOnWeekdaysChangeListener { _: View?, i: Int, list: List<Int?> -> set(DayOfWeek.fromCalendarInt(i), list.contains(i)) }
|
||||
weekdaysPicker.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
weekdaysPicker.sundayFirstDay = Calendar.getInstance().firstDayOfWeek == Calendar.SUNDAY
|
||||
weekdaysPicker.redrawDays()
|
||||
root.addView(weekdaysPicker)
|
||||
|
||||
val timeButton = TextView(root.context)
|
||||
val runAt = GregorianCalendar()
|
||||
runAt[Calendar.HOUR_OF_DAY] = hour
|
||||
runAt[Calendar.MINUTE] = minute
|
||||
timeButton.text = DateUtil.timeString(runAt.timeInMillis)
|
||||
|
||||
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, h, m ->
|
||||
val cal = Calendar.getInstance()
|
||||
hour = h
|
||||
minute = m
|
||||
cal.set(Calendar.HOUR_OF_DAY, hour)
|
||||
cal.set(Calendar.MINUTE, minute)
|
||||
cal.set(Calendar.SECOND, 0)
|
||||
timeButton.text = DateUtil.timeString(cal.timeInMillis)
|
||||
}
|
||||
|
||||
timeButton.setOnClickListener {
|
||||
root.context?.let {
|
||||
TimePickerDialog(it, timeSetListener, hour, minute, DateFormat.is24HourFormat(mainApp))
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
val px = resourceHelper.dpToPx(10)
|
||||
label.text = resourceHelper.gs(R.string.atspecifiedtime, "")
|
||||
label.setTypeface(label.typeface, Typeface.BOLD)
|
||||
label.setPadding(px, px, px, px)
|
||||
timeButton.setPadding(px, px, px, px)
|
||||
val l = LinearLayout(root.context)
|
||||
l.orientation = LinearLayout.HORIZONTAL
|
||||
l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
l.addView(label)
|
||||
l.addView(timeButton)
|
||||
root.addView(l)
|
||||
}
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.StaticLabel;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerTempTarget extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
private ComparatorExists comparator = new ComparatorExists();
|
||||
|
||||
public TriggerTempTarget() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerTempTarget(TriggerTempTarget triggerTempTarget) {
|
||||
super();
|
||||
comparator = new ComparatorExists(triggerTempTarget.comparator);
|
||||
lastRun = triggerTempTarget.lastRun;
|
||||
}
|
||||
|
||||
public ComparatorExists getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
TempTarget tt = TreatmentsPlugin.getPlugin().getTempTargetFromHistory();
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
if (tt == null && comparator.getValue() == ComparatorExists.Compare.NOT_EXISTS) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tt != null && comparator.getValue() == ComparatorExists.Compare.EXISTS) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerTempTarget.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(ComparatorExists.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.careportal_temporarytarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.temptargetcompared, MainApp.gs(comparator.getValue().getStringRes()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.ic_keyboard_tab);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerTempTarget(this);
|
||||
}
|
||||
|
||||
TriggerTempTarget lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TriggerTempTarget comparator(ComparatorExists.Compare compare) {
|
||||
this.comparator = new ComparatorExists().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.careportal_temporarytarget))
|
||||
.add(comparator)
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists
|
||||
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 TriggerTempTarget(mainApp: MainApp) : Trigger(mainApp) {
|
||||
var comparator = ComparatorExists(mainApp)
|
||||
|
||||
constructor(mainApp: MainApp, compare: ComparatorExists.Compare) : this(mainApp) {
|
||||
comparator = ComparatorExists(mainApp, compare)
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, triggerTempTarget: TriggerTempTarget) : this(mainApp) {
|
||||
comparator = ComparatorExists(mainApp, triggerTempTarget.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val tt = treatmentsPlugin.tempTargetFromHistory
|
||||
if (tt == null && comparator.value == ComparatorExists.Compare.NOT_EXISTS) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
if (tt != null && comparator.value == ComparatorExists.Compare.EXISTS) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", TriggerTempTarget::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
comparator.value = ComparatorExists.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.careportal_temporarytarget
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.temptargetcompared, resourceHelper.gs(comparator.value.stringRes))
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_keyboard_tab)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerTempTarget(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.careportal_temporarytarget))
|
||||
.add(comparator)
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -1,186 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerTime extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
private long runAt;
|
||||
|
||||
public TriggerTime() {
|
||||
runAt = DateUtil.now();
|
||||
}
|
||||
|
||||
private TriggerTime(TriggerTime triggerTime) {
|
||||
super();
|
||||
lastRun = triggerTime.lastRun;
|
||||
runAt = triggerTime.runAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRun() {
|
||||
long now = DateUtil.now();
|
||||
if (now >= runAt && now - runAt < T.mins(5).msecs())
|
||||
if (lastRun < runAt) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
data.put("runAt", runAt);
|
||||
data.put("lastRun", lastRun);
|
||||
object.put("type", TriggerTime.class.getName());
|
||||
object.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
JSONObject o;
|
||||
try {
|
||||
o = new JSONObject(data);
|
||||
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
||||
runAt = JsonHelper.safeGetLong(o, "runAt");
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.atspecifiedtime, DateUtil.dateAndTimeString(runAt));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.ic_access_alarm_24dp);
|
||||
}
|
||||
|
||||
TriggerTime runAt(long runAt) {
|
||||
this.runAt = runAt;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerTime(this);
|
||||
}
|
||||
|
||||
long getRunAt() {
|
||||
return runAt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
TextView label = new TextView(root.getContext());
|
||||
TextView dateButton = new TextView(root.getContext());
|
||||
TextView timeButton = new TextView(root.getContext());
|
||||
|
||||
dateButton.setText(DateUtil.dateString(runAt));
|
||||
timeButton.setText(DateUtil.timeString(runAt));
|
||||
dateButton.setOnClickListener(view -> {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
calendar.setTimeInMillis(runAt);
|
||||
DatePickerDialog dpd = DatePickerDialog.newInstance(
|
||||
(view1, year, monthOfYear, dayOfMonth) -> {
|
||||
calendar.set(Calendar.YEAR, year);
|
||||
calendar.set(Calendar.MONTH, monthOfYear);
|
||||
calendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
|
||||
runAt = calendar.getTimeInMillis();
|
||||
dateButton.setText(DateUtil.dateString(runAt));
|
||||
},
|
||||
calendar.get(Calendar.YEAR),
|
||||
calendar.get(Calendar.MONTH),
|
||||
calendar.get(Calendar.DAY_OF_MONTH)
|
||||
);
|
||||
dpd.setThemeDark(true);
|
||||
dpd.dismissOnPause(true);
|
||||
AppCompatActivity a = scanForActivity(root.getContext());
|
||||
if (a != null)
|
||||
dpd.show(a.getSupportFragmentManager(), "DatePickerDialog");
|
||||
});
|
||||
timeButton.setOnClickListener(view -> {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
calendar.setTimeInMillis(runAt);
|
||||
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||
(view12, hourOfDay, minute, second) -> {
|
||||
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
|
||||
calendar.set(Calendar.MINUTE, minute);
|
||||
runAt = calendar.getTimeInMillis();
|
||||
timeButton.setText(DateUtil.timeString(runAt));
|
||||
},
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(root.getContext())
|
||||
);
|
||||
tpd.setThemeDark(true);
|
||||
tpd.dismissOnPause(true);
|
||||
AppCompatActivity a = scanForActivity(root.getContext());
|
||||
if (a != null)
|
||||
tpd.show(a.getSupportFragmentManager(), "TimePickerDialog");
|
||||
});
|
||||
|
||||
int px = MainApp.dpToPx(10);
|
||||
label.setText(MainApp.gs(R.string.atspecifiedtime, ""));
|
||||
label.setTypeface(label.getTypeface(), Typeface.BOLD);
|
||||
label.setPadding(px, px, px, px);
|
||||
dateButton.setPadding(px, px, px, px);
|
||||
timeButton.setPadding(px, px, px, px);
|
||||
|
||||
LinearLayout l = new LinearLayout(root.getContext());
|
||||
l.setOrientation(LinearLayout.HORIZONTAL);
|
||||
l.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
l.addView(label);
|
||||
l.addView(dateButton);
|
||||
l.addView(timeButton);
|
||||
root.addView(l);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.app.DatePickerDialog
|
||||
import android.app.TimePickerDialog
|
||||
import android.graphics.Typeface
|
||||
import android.text.format.DateFormat
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetLong
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
class TriggerTime(mainApp: MainApp) : Trigger(mainApp) {
|
||||
var runAt = DateUtil.now()
|
||||
|
||||
constructor(mainApp: MainApp, runAt: Long) : this(mainApp) {
|
||||
this.runAt = runAt
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, triggerTime : TriggerTime) : this(mainApp) {
|
||||
this.runAt = triggerTime.runAt
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val now = DateUtil.now()
|
||||
if (now >= runAt && now - runAt < T.mins(5).msecs()) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("runAt", runAt)
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val o = JSONObject(data)
|
||||
runAt = safeGetLong(o, "runAt")
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.time
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.atspecifiedtime, DateUtil.dateAndTimeString(runAt))
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_access_alarm_24dp)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerTime(mainApp, runAt)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
val label = TextView(root.context)
|
||||
val dateButton = TextView(root.context)
|
||||
val timeButton = TextView(root.context)
|
||||
dateButton.text = DateUtil.dateString(runAt)
|
||||
timeButton.text = DateUtil.timeString(runAt)
|
||||
|
||||
// create an OnDateSetListener
|
||||
val dateSetListener = DatePickerDialog.OnDateSetListener { _, year, monthOfYear, dayOfMonth ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = runAt
|
||||
cal.set(Calendar.YEAR, year)
|
||||
cal.set(Calendar.MONTH, monthOfYear)
|
||||
cal.set(Calendar.DAY_OF_MONTH, dayOfMonth)
|
||||
runAt = cal.timeInMillis
|
||||
dateButton.text = DateUtil.dateString(runAt)
|
||||
}
|
||||
|
||||
dateButton.setOnClickListener {
|
||||
root.context?.let {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = runAt
|
||||
DatePickerDialog(it, dateSetListener,
|
||||
cal.get(Calendar.YEAR),
|
||||
cal.get(Calendar.MONTH),
|
||||
cal.get(Calendar.DAY_OF_MONTH)
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
// create an OnTimeSetListener
|
||||
val timeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = runAt
|
||||
cal.set(Calendar.HOUR_OF_DAY, hour)
|
||||
cal.set(Calendar.MINUTE, minute)
|
||||
cal.set(Calendar.SECOND, 0) // randomize seconds to prevent creating record of the same time, if user choose time manually
|
||||
runAt = cal.timeInMillis
|
||||
timeButton.text = DateUtil.timeString(runAt)
|
||||
}
|
||||
|
||||
timeButton.setOnClickListener {
|
||||
root.context?.let {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = runAt
|
||||
TimePickerDialog(it, timeSetListener,
|
||||
cal.get(Calendar.HOUR_OF_DAY),
|
||||
cal.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(mainApp)
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
val px = resourceHelper.dpToPx(10)
|
||||
label.text = resourceHelper.gs(R.string.atspecifiedtime, "")
|
||||
label.setTypeface(label.typeface, Typeface.BOLD)
|
||||
label.setPadding(px, px, px, px)
|
||||
dateButton.setPadding(px, px, px, px)
|
||||
timeButton.setPadding(px, px, px, px)
|
||||
val l = LinearLayout(root.context)
|
||||
l.orientation = LinearLayout.HORIZONTAL
|
||||
l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
l.addView(label)
|
||||
l.addView(dateButton)
|
||||
l.addView(timeButton)
|
||||
root.addView(l)
|
||||
}
|
||||
}
|
|
@ -1,235 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.graphics.Typeface;
|
||||
import android.text.format.DateFormat;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
|
||||
// Trigger for time range ( from 10:00AM till 13:00PM )
|
||||
|
||||
public class TriggerTimeRange extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
// in minutes since midnight 60 means 1AM
|
||||
private int start;
|
||||
private int end;
|
||||
long timeZoneOffset = DateUtil.getTimeZoneOffsetMs();
|
||||
|
||||
public TriggerTimeRange() {
|
||||
|
||||
start = getMinSinceMidnight(DateUtil.now());
|
||||
end = getMinSinceMidnight(DateUtil.now());
|
||||
}
|
||||
|
||||
private TriggerTimeRange(TriggerTimeRange triggerTimeRange) {
|
||||
super();
|
||||
lastRun = triggerTimeRange.lastRun;
|
||||
start = triggerTimeRange.start;
|
||||
end = triggerTimeRange.end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRun() {
|
||||
int currentMinSinceMidnight = getMinSinceMidnight(DateUtil.now());
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
boolean doRun = false;
|
||||
if (start < end && start < currentMinSinceMidnight && currentMinSinceMidnight < end)
|
||||
doRun = true;
|
||||
|
||||
// handle cases like 10PM to 6AM
|
||||
else if (start > end && (start < currentMinSinceMidnight || currentMinSinceMidnight < end))
|
||||
doRun = true;
|
||||
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toJSON() {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject data = new JSONObject();
|
||||
|
||||
// check for too big values
|
||||
if (start > 1440)
|
||||
start = getMinSinceMidnight(start);
|
||||
if (end > 1440)
|
||||
end = getMinSinceMidnight(end);
|
||||
|
||||
try {
|
||||
data.put("start", getMinSinceMidnight(start));
|
||||
data.put("end", getMinSinceMidnight(end));
|
||||
data.put("lastRun", lastRun);
|
||||
object.put("type", TriggerTimeRange.class.getName());
|
||||
object.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
log.debug(object.toString());
|
||||
return object.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
TriggerTimeRange fromJSON(String data) {
|
||||
JSONObject o;
|
||||
try {
|
||||
o = new JSONObject(data);
|
||||
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
||||
start = JsonHelper.safeGetInt(o, "start");
|
||||
end = JsonHelper.safeGetInt(o, "end");
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.time_range;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.timerange_value, DateUtil.timeString(toMilis(start) - timeZoneOffset), DateUtil.timeString(toMilis(end) - timeZoneOffset));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.ic_access_alarm_24dp);
|
||||
}
|
||||
|
||||
TriggerTimeRange period(int start, int end) {
|
||||
this.start = getMinSinceMidnight(start * 60000);
|
||||
this.end = getMinSinceMidnight(end * 60000);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTimeRange lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerTimeRange(this);
|
||||
}
|
||||
|
||||
long toMilis(long minutesSinceMidnight) {
|
||||
return minutesSinceMidnight * 60 * 1000;
|
||||
}
|
||||
|
||||
public int getMinSinceMidnight(long time) {
|
||||
// if passed argument is smaller than 1440 ( 24 h * 60 min ) that value is already converted
|
||||
if (0 < time && time < 1441)
|
||||
return (int) time;
|
||||
Calendar calendar = DateUtil.gregorianCalendar();
|
||||
calendar.setTimeInMillis(time);
|
||||
return (calendar.get(Calendar.HOUR_OF_DAY) * 60) + calendar.get(Calendar.MINUTE);
|
||||
}
|
||||
|
||||
int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
TextView label = new TextView(root.getContext());
|
||||
TextView startButton = new TextView(root.getContext());
|
||||
TextView endButton = new TextView(root.getContext());
|
||||
log.debug("Start is: " + start);
|
||||
log.debug("End is: " + end);
|
||||
startButton.setText(DateUtil.timeString(toMilis(start) - timeZoneOffset));
|
||||
endButton.setText(MainApp.gs(R.string.and) + " " + DateUtil.timeString(toMilis(end) - timeZoneOffset));
|
||||
|
||||
startButton.setOnClickListener(view -> {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
//setTimeInMillis sets time in milliseconds after
|
||||
// * January 1, 1970, 0:00:00 GMT., but our time contains timezone offsset
|
||||
calendar.setTimeInMillis(toMilis(start) - timeZoneOffset);
|
||||
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||
(view12, hourOfDay, minute, second) -> {
|
||||
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
|
||||
calendar.set(Calendar.MINUTE, minute);
|
||||
start = getMinSinceMidnight(calendar.getTimeInMillis());
|
||||
startButton.setText(DateUtil.timeString(toMilis(start) - timeZoneOffset));
|
||||
},
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(root.getContext())
|
||||
);
|
||||
tpd.setThemeDark(true);
|
||||
tpd.dismissOnPause(true);
|
||||
AppCompatActivity a = scanForActivity(root.getContext());
|
||||
if (a != null)
|
||||
tpd.show(a.getSupportFragmentManager(), "TimePickerDialog");
|
||||
});
|
||||
endButton.setOnClickListener(view -> {
|
||||
GregorianCalendar calendar = new GregorianCalendar();
|
||||
calendar.setTimeInMillis(toMilis(end) - timeZoneOffset);
|
||||
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||
(view12, hourOfDay, minute, second) -> {
|
||||
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
|
||||
calendar.set(Calendar.MINUTE, minute);
|
||||
end = getMinSinceMidnight(calendar.getTimeInMillis());
|
||||
endButton.setText(MainApp.gs(R.string.and) + " " + DateUtil.timeString(toMilis(end) - timeZoneOffset));
|
||||
},
|
||||
calendar.get(Calendar.HOUR_OF_DAY),
|
||||
calendar.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(root.getContext())
|
||||
);
|
||||
tpd.setThemeDark(true);
|
||||
tpd.dismissOnPause(true);
|
||||
AppCompatActivity a = scanForActivity(root.getContext());
|
||||
if (a != null)
|
||||
tpd.show(a.getSupportFragmentManager(), "TimePickerDialog");
|
||||
});
|
||||
|
||||
int px = MainApp.dpToPx(10);
|
||||
label.setText(MainApp.gs(R.string.between));
|
||||
label.setTypeface(label.getTypeface(), Typeface.BOLD);
|
||||
startButton.setPadding(px, px, px, px);
|
||||
endButton.setPadding(px, px, px, px);
|
||||
|
||||
LinearLayout l = new LinearLayout(root.getContext());
|
||||
l.setOrientation(LinearLayout.HORIZONTAL);
|
||||
l.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||
|
||||
l.addView(label);
|
||||
l.addView(startButton);
|
||||
l.addView(endButton);
|
||||
root.addView(l);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.app.TimePickerDialog
|
||||
import android.graphics.Typeface
|
||||
import android.text.format.DateFormat
|
||||
import android.view.ViewGroup
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
|
||||
// Trigger for time range ( from 10:00AM till 13:00PM )
|
||||
class TriggerTimeRange(mainApp: MainApp) : Trigger(mainApp) {
|
||||
|
||||
// in minutes since midnight 60 means 1AM
|
||||
var start: Int = getMinSinceMidnight(DateUtil.now())
|
||||
var end: Int = getMinSinceMidnight(DateUtil.now())
|
||||
|
||||
constructor(mainApp: MainApp, start : Int, end :Int) : this(mainApp) {
|
||||
this.start = start
|
||||
this.end = end
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, triggerTimeRange: TriggerTimeRange) : this(mainApp) {
|
||||
this.start = triggerTimeRange.start
|
||||
this.end = triggerTimeRange.end
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val currentMinSinceMidnight = getMinSinceMidnight(DateUtil.now())
|
||||
var doRun = false
|
||||
if (start < end && start < currentMinSinceMidnight && currentMinSinceMidnight < end) doRun = true
|
||||
else if (start > end && (start < currentMinSinceMidnight || currentMinSinceMidnight < end)) doRun = true
|
||||
if (doRun) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("start", getMinSinceMidnight(start.toLong()))
|
||||
.put("end", getMinSinceMidnight(end.toLong()))
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): TriggerTimeRange {
|
||||
val o = JSONObject(data)
|
||||
start = safeGetInt(o, "start")
|
||||
end = safeGetInt(o, "end")
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.time_range
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.timerange_value, DateUtil.timeString(toMills(start)), DateUtil.timeString(toMills(end)))
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_access_alarm_24dp)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerTimeRange(mainApp, start, end)
|
||||
|
||||
private fun toMills(minutesSinceMidnight: Int): Long = T.secs(minutesSinceMidnight.toLong()).msecs()
|
||||
|
||||
private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
val label = TextView(root.context)
|
||||
val startButton = TextView(root.context)
|
||||
val endButton = TextView(root.context)
|
||||
startButton.text = DateUtil.timeString(toMills(start))
|
||||
@Suppress("SetTextI18n")
|
||||
endButton.text = resourceHelper.gs(R.string.and) + " " + DateUtil.timeString(toMills(end))
|
||||
|
||||
val startTimeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = toMills(start)
|
||||
cal.set(Calendar.HOUR_OF_DAY, hour)
|
||||
cal.set(Calendar.MINUTE, minute)
|
||||
cal.set(Calendar.SECOND, 0)
|
||||
start = getMinSinceMidnight(cal.timeInMillis)
|
||||
startButton.text = DateUtil.timeString(toMills(start))
|
||||
}
|
||||
|
||||
startButton.setOnClickListener {
|
||||
root.context?.let {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = toMills(start)
|
||||
TimePickerDialog(it, startTimeSetListener,
|
||||
cal.get(Calendar.HOUR_OF_DAY),
|
||||
cal.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(mainApp)
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
val endTimeSetListener = TimePickerDialog.OnTimeSetListener { _, hour, minute ->
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = toMills(end)
|
||||
cal.set(Calendar.HOUR_OF_DAY, hour)
|
||||
cal.set(Calendar.MINUTE, minute)
|
||||
cal.set(Calendar.SECOND, 0) // randomize seconds to prevent creating record of the same time, if user choose time manually
|
||||
end = getMinSinceMidnight(cal.timeInMillis)
|
||||
endButton.text = DateUtil.timeString(toMills(end))
|
||||
}
|
||||
|
||||
endButton.setOnClickListener {
|
||||
root.context?.let {
|
||||
val cal = Calendar.getInstance()
|
||||
cal.timeInMillis = toMills(end)
|
||||
TimePickerDialog(it, endTimeSetListener,
|
||||
cal.get(Calendar.HOUR_OF_DAY),
|
||||
cal.get(Calendar.MINUTE),
|
||||
DateFormat.is24HourFormat(mainApp)
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
val px = resourceHelper.dpToPx(10)
|
||||
label.text = resourceHelper.gs(R.string.between)
|
||||
label.setTypeface(label.typeface, Typeface.BOLD)
|
||||
startButton.setPadding(px, px, px, px)
|
||||
endButton.setPadding(px, px, px, px)
|
||||
val l = LinearLayout(root.context)
|
||||
l.orientation = LinearLayout.HORIZONTAL
|
||||
l.layoutParams = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
l.addView(label)
|
||||
l.addView(startButton)
|
||||
l.addView(endButton)
|
||||
root.addView(l)
|
||||
}
|
||||
}
|
|
@ -1,149 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.events.EventNetworkChange;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputString;
|
||||
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.receivers.NetworkChangeReceiver;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.JsonHelper;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
public class TriggerWifiSsid extends Trigger {
|
||||
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
|
||||
|
||||
private InputString ssid = new InputString();
|
||||
private Comparator comparator = new Comparator();
|
||||
|
||||
public TriggerWifiSsid() {
|
||||
super();
|
||||
}
|
||||
|
||||
private TriggerWifiSsid(TriggerWifiSsid triggerWifiSsid) {
|
||||
super();
|
||||
ssid = new InputString(triggerWifiSsid.ssid);
|
||||
comparator = new Comparator(triggerWifiSsid.comparator);
|
||||
lastRun = triggerWifiSsid.lastRun;
|
||||
}
|
||||
|
||||
public String getValue() {
|
||||
return ssid.getValue();
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return comparator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean shouldRun() {
|
||||
EventNetworkChange eventNetworkChange = NetworkChangeReceiver.getLastEvent();
|
||||
if (eventNetworkChange == null)
|
||||
return false;
|
||||
|
||||
if (lastRun > DateUtil.now() - T.mins(5).msecs())
|
||||
return false;
|
||||
|
||||
if (!eventNetworkChange.getWifiConnected() && comparator.getValue() == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean doRun = eventNetworkChange.getWifiConnected() && comparator.getValue().check(eventNetworkChange.connectedSsid(), getValue());
|
||||
if (doRun) {
|
||||
if (L.isEnabled(L.AUTOMATION))
|
||||
log.debug("Ready for execution: " + friendlyDescription());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerWifiSsid.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("ssid", getValue());
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("comparator", comparator.getValue().toString());
|
||||
o.put("data", data);
|
||||
} catch (JSONException e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
ssid.setValue(JsonHelper.safeGetString(d, "ssid"));
|
||||
lastRun = JsonHelper.safeGetLong(d, "lastRun");
|
||||
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
|
||||
} catch (Exception e) {
|
||||
log.error("Unhandled exception", e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int friendlyName() {
|
||||
return R.string.ns_wifi_ssids;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String friendlyDescription() {
|
||||
return MainApp.gs(R.string.wifissidcompared, MainApp.gs(comparator.getValue().getStringRes()), getValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> icon() {
|
||||
return Optional.of(R.drawable.ic_network_wifi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Trigger duplicate() {
|
||||
return new TriggerWifiSsid(this);
|
||||
}
|
||||
|
||||
TriggerWifiSsid setValue(String value) {
|
||||
ssid.setValue(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerWifiSsid lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerWifiSsid comparator(Comparator.Compare compare) {
|
||||
this.comparator = new Comparator().setValue(compare);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
|
||||
new LayoutBuilder()
|
||||
.add(new StaticLabel(R.string.ns_wifi_ssids))
|
||||
.add(comparator)
|
||||
.add(new LabelWithElement(MainApp.gs(R.string.ns_wifi_ssids) + ": ", "", ssid))
|
||||
.build(root);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.triggers
|
||||
|
||||
import android.widget.LinearLayout
|
||||
import com.google.common.base.Optional
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputString
|
||||
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.receivers.NetworkChangeReceiver
|
||||
import info.nightscout.androidaps.utils.JsonHelper
|
||||
import org.json.JSONObject
|
||||
|
||||
class TriggerWifiSsid(mainApp: MainApp) : Trigger(mainApp) {
|
||||
private var ssid = InputString(mainApp)
|
||||
var comparator = Comparator(mainApp)
|
||||
|
||||
constructor(mainApp: MainApp, ssid: String, compare: Comparator.Compare) : this(mainApp) {
|
||||
this.ssid = InputString(mainApp, ssid)
|
||||
comparator = Comparator(mainApp, compare)
|
||||
}
|
||||
|
||||
constructor(mainApp: MainApp, triggerWifiSsid: TriggerWifiSsid) : this(mainApp) {
|
||||
this.ssid = InputString(mainApp, triggerWifiSsid.ssid.value)
|
||||
comparator = Comparator(mainApp, triggerWifiSsid.comparator.value)
|
||||
}
|
||||
|
||||
override fun shouldRun(): Boolean {
|
||||
val eventNetworkChange = NetworkChangeReceiver.getLastEvent() ?: return false
|
||||
if (!eventNetworkChange.wifiConnected && comparator.value == Comparator.Compare.IS_NOT_AVAILABLE) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
if (eventNetworkChange.wifiConnected && comparator.value.check(eventNetworkChange.connectedSsid(), ssid.value)) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Ready for execution: " + friendlyDescription())
|
||||
return true
|
||||
}
|
||||
aapsLogger.debug(LTag.AUTOMATION, "NOT ready for execution: " + friendlyDescription())
|
||||
return false
|
||||
}
|
||||
|
||||
override fun toJSON(): String {
|
||||
val data = JSONObject()
|
||||
.put("ssid", ssid)
|
||||
.put("comparator", comparator.value.toString())
|
||||
return JSONObject()
|
||||
.put("type", this::class.java.name)
|
||||
.put("data", data)
|
||||
.toString()
|
||||
}
|
||||
|
||||
override fun fromJSON(data: String): Trigger {
|
||||
val d = JSONObject(data)
|
||||
ssid.value = JsonHelper.safeGetString(d, "ssid")!!
|
||||
comparator.value = Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")!!)
|
||||
return this
|
||||
}
|
||||
|
||||
override fun friendlyName(): Int = R.string.ns_wifi_ssids
|
||||
|
||||
override fun friendlyDescription(): String =
|
||||
resourceHelper.gs(R.string.wifissidcompared, resourceHelper.gs(comparator.value.stringRes), ssid.value)
|
||||
|
||||
override fun icon(): Optional<Int?> = Optional.of(R.drawable.ic_network_wifi)
|
||||
|
||||
override fun duplicate(): Trigger = TriggerWifiSsid(mainApp, this)
|
||||
|
||||
override fun generateDialog(root: LinearLayout) {
|
||||
LayoutBuilder()
|
||||
.add(StaticLabel(mainApp, R.string.ns_wifi_ssids))
|
||||
.add(comparator)
|
||||
.add(LabelWithElement(mainApp, resourceHelper.gs(R.string.ns_wifi_ssids) + ": ", "", ssid))
|
||||
.build(root)
|
||||
}
|
||||
}
|
|
@ -8,10 +8,12 @@ import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
|
|||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Created by adrian on 14/08/17.
|
||||
*/
|
||||
@Singleton
|
||||
class InsulinOrefRapidActingPlugin @Inject constructor(
|
||||
resourceHelper: ResourceHelper,
|
||||
rxBus: RxBusWrapper,
|
||||
|
|
|
@ -8,10 +8,12 @@ import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
|
|||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Created by adrian on 14/08/17.
|
||||
*/
|
||||
@Singleton
|
||||
class InsulinOrefUltraRapidActingPlugin @Inject constructor(
|
||||
private val sp: SP,
|
||||
resourceHelper: ResourceHelper,
|
||||
|
|
|
@ -26,7 +26,7 @@ import io.reactivex.disposables.CompositeDisposable
|
|||
import io.reactivex.schedulers.Schedulers
|
||||
import javax.inject.Inject
|
||||
|
||||
class LocationService : DaggerService() {
|
||||
class LocationService @Inject constructor(): DaggerService() {
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var sp: SP
|
||||
|
@ -40,13 +40,10 @@ class LocationService : DaggerService() {
|
|||
private val LOCATION_INTERVAL_ACTIVE = T.mins(5).msecs()
|
||||
private val LOCATION_INTERVAL_PASSIVE = T.mins(1).msecs() // this doesn't cost more power
|
||||
|
||||
var lastLocation: Location? = null
|
||||
|
||||
companion object {
|
||||
private const val LOCATION_DISTANCE = 10f
|
||||
private var lastLocation: Location? = null
|
||||
|
||||
@JvmStatic
|
||||
@Deprecated("replace by injection")
|
||||
fun getLastLocation(): Location? = lastLocation
|
||||
}
|
||||
|
||||
inner class LocationListener internal constructor(val provider: String) : android.location.LocationListener {
|
||||
|
|
|
@ -81,13 +81,6 @@ public class TriggerAutosensValueTest {
|
|||
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.getComparator().getValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void executeTest() {
|
||||
TriggerAutosensValue t = new TriggerAutosensValue().setValue(213).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER);
|
||||
t.executed(1);
|
||||
Assert.assertEquals(1l, t.getLastRun());
|
||||
}
|
||||
|
||||
String ASJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"lastRun\":0,\"value\":410},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerAutosensValue\"}";
|
||||
|
||||
@Test
|
||||
|
|
|
@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.insulin
|
|||
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import junit.framework.Assert.assertEquals
|
||||
|
@ -34,10 +35,11 @@ class InsulinOrefFreePeakPluginTest {
|
|||
@Mock lateinit var sp: SP
|
||||
@Mock lateinit var resourceHelper: ResourceHelper
|
||||
@Mock lateinit var rxBus: RxBusWrapper
|
||||
@Mock lateinit var profileFunction: ProfileFunction
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
sut = InsulinOrefFreePeakPlugin(sp, resourceHelper, rxBus)
|
||||
sut = InsulinOrefFreePeakPlugin(sp, resourceHelper, rxBus, profileFunction)
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
Loading…
Reference in a new issue