diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt index 81261d3266..315acdb618 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt @@ -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 { 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 { 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) diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt index 7fa6cef715..3f8228e35e 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppModule.kt @@ -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 diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.java deleted file mode 100644 index eb38b24fb6..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.java +++ /dev/null @@ -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 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 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; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.kt new file mode 100644 index 0000000000..26e4f74278 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationEvent.kt @@ -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 = 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() + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt index 0310d5cc9c..5c9092c9e1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationFragment.kt @@ -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) { + 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(), 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() - TriggerConnector.fillIconSet(event.trigger as TriggerConnector, triggerIcons) + fillIconSet(event.trigger as TriggerConnector, triggerIcons) for (res in triggerIcons) { addImage(res, holder.context, holder.iconLayout) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt index 7246f0a7ad..8678192f33 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/AutomationPlugin.kt @@ -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 { 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) ) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/Action.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/Action.kt index cd23ff7e62..590638f86e 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/Action.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/Action.kt @@ -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) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt index c2f3bc73c7..5cad5f333d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionLoopSuspend.kt @@ -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) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt index 88d80b114c..eee0ab86c2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionNotification.kt @@ -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) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt index 23585ca992..1c797cdc19 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitch.kt @@ -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 } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt index d37893997d..3882da1906 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionProfileSwitchPercent.kt @@ -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 } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt index ea6424981f..84b10feb65 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionSendSMS.kt @@ -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) } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt index 9d35d265d6..d497fb9bd1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionStartTempTarget.kt @@ -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)) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.kt index 882612f77b..183537a53b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseActionDialog.kt @@ -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 } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseTriggerDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseTriggerDialog.kt index 1cafa61f38..8721273afa 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseTriggerDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/ChooseTriggerDialog.kt @@ -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(radioButtonID) return radioButton?.let { - it.tag as Class<*> + it.tag as String } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditEventDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditEventDialog.kt index e84afaf7ae..21a62bc0a5 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditEventDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditEventDialog.kt @@ -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 diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt index 984c892e8d..1b56362902 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/EditTriggerDialog.kt @@ -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 { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java index 3daa0fbd17..93f5378529 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/dialogs/TriggerListAdapter.java @@ -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 spinnerArrayAdapter = new ArrayAdapter<>(mContext, R.layout.spinner_centered, TriggerConnector.Type.labels()); + ArrayAdapter 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); } - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Comparator.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Comparator.java deleted file mode 100644 index c0e23d979c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Comparator.java +++ /dev/null @@ -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 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 labels() { - List 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 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; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Comparator.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Comparator.kt new file mode 100644 index 0000000000..f965224281 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Comparator.kt @@ -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 > 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 { + val list: MutableList = 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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/ComparatorExists.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/ComparatorExists.java deleted file mode 100644 index 4bc0082afa..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/ComparatorExists.java +++ /dev/null @@ -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 labels() { - List 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 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; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/ComparatorExists.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/ComparatorExists.kt new file mode 100644 index 0000000000..1fa8ec1b6a --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/ComparatorExists.kt @@ -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 { + val list: MutableList = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Element.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Element.java deleted file mode 100644 index a853fde1e7..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Element.java +++ /dev/null @@ -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); -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Element.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Element.kt new file mode 100644 index 0000000000..7a9f74289f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/Element.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java deleted file mode 100644 index ff4781552a..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.java +++ /dev/null @@ -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; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.kt new file mode 100644 index 0000000000..fb8b45f83d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputBg.kt @@ -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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputButton.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputButton.java deleted file mode 100644 index 6b0406abe0..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputButton.java +++ /dev/null @@ -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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputButton.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputButton.kt new file mode 100644 index 0000000000..866e9c4423 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputButton.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.java deleted file mode 100644 index 4dc9358f6c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.java +++ /dev/null @@ -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 labels() { - List 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 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; - } - -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.kt new file mode 100644 index 0000000000..d1bf5dfbf8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDelta.kt @@ -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 { + val list: MutableList = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDouble.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDouble.java deleted file mode 100644 index 518b00f5b4..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDouble.java +++ /dev/null @@ -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; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDouble.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDouble.kt new file mode 100644 index 0000000000..5a63cddcfb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDouble.kt @@ -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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDuration.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDuration.java deleted file mode 100644 index aa19896471..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDuration.java +++ /dev/null @@ -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; - } - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDuration.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDuration.kt new file mode 100644 index 0000000000..777137316c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputDuration.kt @@ -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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputInsulin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputInsulin.java deleted file mode 100644 index 8cf89d3b42..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputInsulin.java +++ /dev/null @@ -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; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputInsulin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputInsulin.kt new file mode 100644 index 0000000000..01651dc780 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputInsulin.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputLocationMode.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputLocationMode.java deleted file mode 100644 index 3fea8b7c33..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputLocationMode.java +++ /dev/null @@ -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 labels() { - List 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 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; - } - - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputLocationMode.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputLocationMode.kt new file mode 100644 index 0000000000..9571e9da83 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputLocationMode.kt @@ -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 { + val list: MutableList = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputPercent.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputPercent.java deleted file mode 100644 index bade9082a3..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputPercent.java +++ /dev/null @@ -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; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputPercent.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputPercent.kt new file mode 100644 index 0000000000..6412bfb6cd --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputPercent.kt @@ -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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.java deleted file mode 100644 index 5431f47ede..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.java +++ /dev/null @@ -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 profileList = new ArrayList<>(); - profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile(); - if (profileStore == null) { - log.error("ProfileStore is empty"); - } else { - profileList = profileStore.getProfileList(); - } - ArrayAdapter 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 listNames(){ - ArrayList profileList = new ArrayList<>(); - // profile - profileStore = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile(); - if (profileStore == null) { - log.error("ProfileStore is empty"); - } else { - profileList = profileStore.getProfileList(); - } - return profileList; - } - - -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.kt new file mode 100644 index 0000000000..bacd1cb3a8 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputProfileName.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.java deleted file mode 100644 index 75ddb4b61a..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.java +++ /dev/null @@ -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; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.kt new file mode 100644 index 0000000000..a857fb2ecb --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputString.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java deleted file mode 100644 index e0fabcf0dd..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.java +++ /dev/null @@ -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; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.kt new file mode 100644 index 0000000000..eb41a02879 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/InputTempTarget.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LabelWithElement.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LabelWithElement.java deleted file mode 100644 index 145d8c2d2c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LabelWithElement.java +++ /dev/null @@ -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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LabelWithElement.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LabelWithElement.kt new file mode 100644 index 0000000000..5666e0e9f9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LabelWithElement.kt @@ -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) + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LayoutBuilder.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LayoutBuilder.java deleted file mode 100644 index 5853e50be0..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LayoutBuilder.java +++ /dev/null @@ -1,26 +0,0 @@ -package info.nightscout.androidaps.plugins.general.automation.elements; - -import android.widget.LinearLayout; - -import java.util.ArrayList; - -public class LayoutBuilder { - ArrayList 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); - } - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LayoutBuilder.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LayoutBuilder.kt new file mode 100644 index 0000000000..a23467ea3d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/LayoutBuilder.kt @@ -0,0 +1,23 @@ +package info.nightscout.androidaps.plugins.general.automation.elements + +import android.widget.LinearLayout +import java.util.* + +class LayoutBuilder { + var mElements = ArrayList() + 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) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.java deleted file mode 100644 index 3c8cf38074..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.java +++ /dev/null @@ -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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.kt new file mode 100644 index 0000000000..807e4cc7f0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/elements/StaticLabel.kt @@ -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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.java deleted file mode 100644 index c1bca15028..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.java +++ /dev/null @@ -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 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; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.kt new file mode 100644 index 0000000000..4db2cc5bd3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/Trigger.kt @@ -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 + 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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.java deleted file mode 100644 index ce0a8f63bb..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.java +++ /dev/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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.kt new file mode 100644 index 0000000000..c2e552e7de --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValue.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.java deleted file mode 100644 index 3733859b96..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.kt new file mode 100644 index 0000000000..1346ed7daa --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBg.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.java deleted file mode 100644 index 0a038112e2..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt new file mode 100644 index 0000000000..4edbd03bc7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerBolusAgo.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.java deleted file mode 100644 index bf17dc72d1..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.kt new file mode 100644 index 0000000000..54df75427c --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerCOB.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.java deleted file mode 100644 index 549925528a..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.java +++ /dev/null @@ -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 labels() { - List list = new ArrayList<>(); - for (Type t : values()) { - list.add(MainApp.gs(t.getStringRes())); - } - return list; - } - } - - public static void fillIconSet(TriggerConnector connector, HashSet set) { - for (Trigger t : connector.list) { - if (t instanceof TriggerConnector) { - fillIconSet((TriggerConnector) t, set); - } else { - Optional icon = t.icon(); - if (icon.isPresent()) { - set.add(icon.get()); - } - } - } - } - - protected List 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 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; - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.kt new file mode 100644 index 0000000000..2e74124d19 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerConnector.kt @@ -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 = 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 { + val list: MutableList = 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 = 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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java deleted file mode 100644 index 6fb2053fbc..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.java +++ /dev/null @@ -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 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); - } - -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.kt new file mode 100644 index 0000000000..d44ab280c7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDelta.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDummy.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDummy.kt new file mode 100644 index 0000000000..8f7982db52 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerDummy.kt @@ -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 { + throw NotImplementedError("An operation is not implemented") + } + + override fun duplicate(): Trigger { + throw NotImplementedError("An operation is not implemented") + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.java deleted file mode 100644 index a3935d7cec..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.kt new file mode 100644 index 0000000000..9c81937ed9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerIob.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.java deleted file mode 100644 index 521f7df9a5..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.java +++ /dev/null @@ -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 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(); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.kt new file mode 100644 index 0000000000..5a7c48db3d --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerLocation.kt @@ -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 = 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 + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.java deleted file mode 100644 index e4c0ae4346..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.kt new file mode 100644 index 0000000000..bcdcf48af3 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerProfilePercent.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.java deleted file mode 100644 index ff8bb335f9..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.kt new file mode 100644 index 0000000000..aec4cfee4f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerPumpLastConnection.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.java deleted file mode 100644 index 2031dbc74c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.java +++ /dev/null @@ -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 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 getSelectedDays() { - List 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); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt new file mode 100644 index 0000000000..35a4433ba1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerRecurringTime.kt @@ -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 = Optional.of(R.drawable.ic_access_alarm_24dp) + + override fun duplicate(): Trigger = TriggerRecurringTime(mainApp, this) + + private fun getSelectedDays(): List { + val selectedDays: MutableList = 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 -> 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.java deleted file mode 100644 index a5fc6ba092..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.kt new file mode 100644 index 0000000000..edd144f14f --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTempTarget.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.java deleted file mode 100644 index 91e739ca45..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.kt new file mode 100644 index 0000000000..4e5af1db97 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTime.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.java deleted file mode 100644 index 082c5af75c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.kt new file mode 100644 index 0000000000..d42de467e7 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerTimeRange.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.java deleted file mode 100644 index dd2c34bcb8..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.java +++ /dev/null @@ -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 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); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.kt new file mode 100644 index 0000000000..83da0d1f44 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerWifiSsid.kt @@ -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 = 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) + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPlugin.kt index b9fc161743..43dbbe733d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefRapidActingPlugin.kt @@ -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, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt index d09492053e..75a757065c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefUltraRapidActingPlugin.kt @@ -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, diff --git a/app/src/main/java/info/nightscout/androidaps/services/LocationService.kt b/app/src/main/java/info/nightscout/androidaps/services/LocationService.kt index f638358431..54e25c2f54 100644 --- a/app/src/main/java/info/nightscout/androidaps/services/LocationService.kt +++ b/app/src/main/java/info/nightscout/androidaps/services/LocationService.kt @@ -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 { diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValueTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValueTest.java index dd2a4a533e..b266b44d38 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValueTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/automation/triggers/TriggerAutosensValueTest.java @@ -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 diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPluginTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPluginTest.kt index 9adb089ff4..ef2e48d182 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPluginTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/insulin/InsulinOrefFreePeakPluginTest.kt @@ -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