Actions injection

This commit is contained in:
Milos Kozak 2020-01-02 19:20:36 +01:00
parent bcc3829915
commit 8faf36295f
33 changed files with 797 additions and 1271 deletions

View file

@ -8,7 +8,7 @@ import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.db.BgReading import info.nightscout.androidaps.db.BgReading
import info.nightscout.androidaps.plugins.aps.openAPSMA.LoggerCallback import info.nightscout.androidaps.plugins.aps.openAPSMA.LoggerCallback
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.* import info.nightscout.androidaps.plugins.constraints.objectives.objectives.*
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS import info.nightscout.androidaps.plugins.general.automation.actions.*
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.plugins.treatments.Treatment
import info.nightscout.androidaps.queue.commands.CommandSetProfile import info.nightscout.androidaps.queue.commands.CommandSetProfile
@ -31,8 +31,6 @@ interface AppComponent : AndroidInjector<MainApp> {
fun injectCommandSetProfile(commandSetProfile: CommandSetProfile) fun injectCommandSetProfile(commandSetProfile: CommandSetProfile)
fun injectActionSendSMS(actionSendSMS: ActionSendSMS)
fun injectObjective0(objective0: Objective0) fun injectObjective0(objective0: Objective0)
fun injectObjective1(objective1: Objective1) fun injectObjective1(objective1: Objective1)
fun injectObjective2(objective2: Objective2) fun injectObjective2(objective2: Objective2)
@ -40,6 +38,19 @@ interface AppComponent : AndroidInjector<MainApp> {
fun injectObjective5(objective5: Objective5) fun injectObjective5(objective5: Objective5)
fun injectObjective6(objective6: Objective6) fun injectObjective6(objective6: Objective6)
fun injectAction(action: Action)
fun injectActionDummy(action: ActionDummy)
fun injectActionLoopDisable(action: ActionLoopDisable)
fun injectActionLoopEnable(action: ActionLoopEnable)
fun injectActionLoopResume(action: ActionLoopResume)
fun injectAction(action: ActionLoopSuspend)
fun injectActionLoopSuspend(action: ActionNotification)
fun injectActionProfileSwitch(action: ActionProfileSwitch)
fun injectAction(action: ActionProfileSwitchPercent)
fun injectActionProfileSwitchPercent(action: ActionSendSMS)
fun injectActionStartTempTarget(action: ActionStartTempTarget)
fun injectActionStopTempTarget(action: ActionStopTempTarget)
fun injectTreatment(treatment: Treatment) fun injectTreatment(treatment: Treatment)
fun injectBgReading(bgReading: BgReading) fun injectBgReading(bgReading: BgReading)

View file

@ -17,7 +17,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctionImplementation
import info.nightscout.androidaps.plugins.constraints.objectives.objectives.* import info.nightscout.androidaps.plugins.constraints.objectives.objectives.*
import info.nightscout.androidaps.plugins.general.automation.actions.ActionSendSMS import info.nightscout.androidaps.plugins.general.automation.actions.*
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.treatments.Treatment import info.nightscout.androidaps.plugins.treatments.Treatment
import info.nightscout.androidaps.queue.commands.CommandSetProfile import info.nightscout.androidaps.queue.commands.CommandSetProfile
@ -64,7 +64,6 @@ open class AppModule {
interface AppBindings { interface AppBindings {
@ContributesAndroidInjector fun commandSetProfileInjector(): CommandSetProfile @ContributesAndroidInjector fun commandSetProfileInjector(): CommandSetProfile
@ContributesAndroidInjector fun actionSendSMSInjector(): ActionSendSMS
@ContributesAndroidInjector fun objective0Injector(): Objective0 @ContributesAndroidInjector fun objective0Injector(): Objective0
@ContributesAndroidInjector fun objective1Injector(): Objective1 @ContributesAndroidInjector fun objective1Injector(): Objective1
@ContributesAndroidInjector fun objective2Injector(): Objective2 @ContributesAndroidInjector fun objective2Injector(): Objective2
@ -72,6 +71,19 @@ open class AppModule {
@ContributesAndroidInjector fun objective5Injector(): Objective5 @ContributesAndroidInjector fun objective5Injector(): Objective5
@ContributesAndroidInjector fun objective6Injector(): Objective6 @ContributesAndroidInjector fun objective6Injector(): Objective6
@ContributesAndroidInjector fun actionInjector(): Action
@ContributesAndroidInjector fun actionLoopDisableInjector(): ActionLoopDisable
@ContributesAndroidInjector fun actionLoopEnableInjector(): ActionLoopEnable
@ContributesAndroidInjector fun ActionLoopResumeInjector(): ActionLoopResume
@ContributesAndroidInjector fun actionLoopSuspendInjector(): ActionLoopSuspend
@ContributesAndroidInjector fun actionNotificationInjector(): ActionNotification
@ContributesAndroidInjector fun actionProfileSwitchInjector(): ActionProfileSwitch
@ContributesAndroidInjector fun actionProfileSwitchPercentInjector(): ActionProfileSwitchPercent
@ContributesAndroidInjector fun actionSendSMSInjector(): ActionSendSMS
@ContributesAndroidInjector fun actionStartTempTargetInjector(): ActionStartTempTarget
@ContributesAndroidInjector fun actionStopTempTargetInjector(): ActionStopTempTarget
@ContributesAndroidInjector fun actionDummyInjector(): ActionDummy
@ContributesAndroidInjector fun bgReadingInjector(): BgReading @ContributesAndroidInjector fun bgReadingInjector(): BgReading
@ContributesAndroidInjector fun treatmentInjector(): Treatment @ContributesAndroidInjector fun treatmentInjector(): Treatment

View file

@ -7,7 +7,9 @@ import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; 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.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.Trigger;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector; import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -48,8 +50,8 @@ public class AutomationEvent {
public TriggerConnector getPreconditions() { public TriggerConnector getPreconditions() {
TriggerConnector trigger = new TriggerConnector(TriggerConnector.Type.AND); TriggerConnector trigger = new TriggerConnector(TriggerConnector.Type.AND);
for (Action action : actions) { for (Action action : actions) {
if (action.precondition != null) if (action.getPrecondition() != null)
trigger.add(action.precondition); trigger.add(action.getPrecondition());
} }
return trigger; return trigger;
} }
@ -91,7 +93,7 @@ public class AutomationEvent {
JSONArray array = d.getJSONArray("actions"); JSONArray array = d.getJSONArray("actions");
actions.clear(); actions.clear();
for (int i = 0; i < array.length(); i++) { for (int i = 0; i < array.length(); i++) {
actions.add(Action.instantiate(new JSONObject(array.getString(i)))); actions.add(new ActionDummy(MainApp.instance()).instantiate(new JSONObject(array.getString(i))));
} }
} catch (JSONException e) { } catch (JSONException e) {
log.error("Unhandled exception", e); log.error("Unhandled exception", e);

View file

@ -1,30 +1,48 @@
package info.nightscout.androidaps.plugins.general.automation package info.nightscout.androidaps.plugins.general.automation
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.os.Bundle import android.os.Bundle
import android.text.method.ScrollingMovementMethod import android.text.method.ScrollingMovementMethod
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.CheckBox
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.RelativeLayout
import android.widget.TextView
import androidx.annotation.DrawableRes
import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperAdapter
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperViewHolder
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.OnStartDragListener import info.nightscout.androidaps.plugins.general.automation.dragHelpers.OnStartDragListener
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.SimpleItemTouchHelperCallback import info.nightscout.androidaps.plugins.general.automation.dragHelpers.SimpleItemTouchHelperCallback
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.utils.OKDialog.showConfirmation
import info.nightscout.androidaps.utils.extensions.plusAssign import info.nightscout.androidaps.utils.extensions.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.automation_fragment.* import kotlinx.android.synthetic.main.automation_fragment.*
import java.util.*
import javax.inject.Inject import javax.inject.Inject
class AutomationFragment : DaggerFragment(), OnStartDragListener { class AutomationFragment : DaggerFragment(), OnStartDragListener {
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var automationPlugin: AutomationPlugin @Inject lateinit var automationPlugin: AutomationPlugin
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@ -40,7 +58,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
eventListAdapter = EventListAdapter(automationPlugin.automationEvents, fragmentManager, activity, this) eventListAdapter = EventListAdapter()
automation_eventListView.layoutManager = LinearLayoutManager(context) automation_eventListView.layoutManager = LinearLayoutManager(context)
automation_eventListView.adapter = eventListAdapter automation_eventListView.adapter = eventListAdapter
@ -102,4 +120,100 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
itemTouchHelper?.startDrag(viewHolder) itemTouchHelper?.startDrag(viewHolder)
} }
inner class EventListAdapter : RecyclerView.Adapter<EventListAdapter.ViewHolder>(), ItemTouchHelperAdapter {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.automation_event_item, parent, false)
return ViewHolder(v, parent.context)
}
private fun addImage(@DrawableRes res: Int, context: Context, layout: LinearLayout) {
val iv = ImageView(context)
iv.setImageResource(res)
iv.layoutParams = LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24))
layout.addView(iv)
}
@SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val event = automationPlugin.automationEvents[position]
holder.eventTitle.text = event.title
holder.enabled.isChecked = event.isEnabled
holder.iconLayout.removeAllViews()
// trigger icons
val triggerIcons = HashSet<Int>()
TriggerConnector.fillIconSet(event.trigger as TriggerConnector, triggerIcons)
for (res in triggerIcons) {
addImage(res, holder.context, holder.iconLayout)
}
// arrow icon
val iv = ImageView(holder.context)
iv.setImageResource(R.drawable.ic_arrow_forward_white_24dp)
iv.layoutParams = LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24))
iv.setPadding(MainApp.dpToPx(4), 0, MainApp.dpToPx(4), 0)
holder.iconLayout.addView(iv)
// action icons
val actionIcons = HashSet<Int>()
for (action in event.actions) {
actionIcons.add(action.icon())
}
for (res in actionIcons) {
addImage(res, holder.context, holder.iconLayout)
}
// enabled event
holder.enabled.setOnClickListener {
event.isEnabled = holder.enabled.isChecked
rxBus.send(EventAutomationDataChanged())
}
// edit event
holder.rootLayout.setOnClickListener {
val dialog = EditEventDialog()
val args = Bundle()
args.putString("event", event.toJSON())
args.putInt("position", position)
dialog.arguments = args
fragmentManager?.let { dialog.show(it, "EditEventDialog") }
}
// Start a drag whenever the handle view it touched
holder.iconSort.setOnTouchListener { v: View, motionEvent: MotionEvent ->
if (motionEvent.action == MotionEvent.ACTION_DOWN) {
this@AutomationFragment.onStartDrag(holder)
return@setOnTouchListener true
}
v.onTouchEvent(motionEvent)
}
}
override fun getItemCount(): Int = automationPlugin.automationEvents.size
override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
Collections.swap(automationPlugin.automationEvents, fromPosition, toPosition)
notifyItemMoved(fromPosition, toPosition)
rxBus.send(EventAutomationDataChanged())
return true
}
override fun onItemDismiss(position: Int) {
activity?.let { activity ->
showConfirmation(activity, resourceHelper.gs(R.string.removerecord) + " " + automationPlugin.automationEvents[position].title,
Runnable {
automationPlugin.automationEvents.removeAt(position)
notifyItemRemoved(position)
rxBus.send(EventAutomationDataChanged())
rxBus.send(EventAutomationUpdateGui())
}, Runnable { rxBus.send(EventAutomationUpdateGui()) })
}
}
inner class ViewHolder(view: View, val context: Context) : RecyclerView.ViewHolder(view), ItemTouchHelperViewHolder {
val rootLayout: RelativeLayout = view.findViewById(R.id.rootLayout)
val iconLayout: LinearLayout = view.findViewById(R.id.iconLayout)
val eventTitle: TextView = view.findViewById(R.id.viewEventTitle)
val iconSort: ImageView = view.findViewById(R.id.iconSort)
val enabled: CheckBox = view.findViewById(R.id.automation_enabled)
override fun onItemSelected() = itemView.setBackgroundColor(Color.LTGRAY)
override fun onItemClear() = itemView.setBackgroundColor(resourceHelper.gc(R.color.ribbonDefault))
}
}
} }

View file

@ -207,16 +207,16 @@ class AutomationPlugin @Inject constructor(
fun getActionDummyObjects(): List<Action> { fun getActionDummyObjects(): List<Action> {
return listOf( return listOf(
//ActionLoopDisable(), //ActionLoopDisable(mainApp),
//ActionLoopEnable(), //ActionLoopEnable(mainApp),
//ActionLoopResume(), //ActionLoopResume(mainApp),
//ActionLoopSuspend(), //ActionLoopSuspend(mainApp),
ActionStartTempTarget(), ActionStartTempTarget(mainApp),
ActionStopTempTarget(), ActionStopTempTarget(mainApp),
ActionNotification(), ActionNotification(mainApp),
ActionProfileSwitchPercent(), ActionProfileSwitchPercent(mainApp),
ActionProfileSwitch(), ActionProfileSwitch(mainApp),
ActionSendSMS() ActionSendSMS(mainApp)
) )
} }

View file

@ -1,186 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.RecyclerView;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog;
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperAdapter;
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.ItemTouchHelperViewHolder;
import info.nightscout.androidaps.plugins.general.automation.dragHelpers.OnStartDragListener;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
import info.nightscout.androidaps.utils.OKDialog;
class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder> implements ItemTouchHelperAdapter {
private final List<AutomationEvent> eventList;
private final FragmentManager fragmentManager;
private final Activity activity;
private final OnStartDragListener mDragStartListener;
EventListAdapter(List<AutomationEvent> events, FragmentManager fragmentManager, Activity activity, OnStartDragListener dragStartListener) {
this.eventList = events;
this.fragmentManager = fragmentManager;
this.activity = activity;
mDragStartListener = dragStartListener;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.automation_event_item, parent, false);
return new ViewHolder(v, parent.getContext());
}
private void addImage(@DrawableRes int res, Context context, LinearLayout layout) {
ImageView iv = new ImageView(context);
iv.setImageResource(res);
iv.setLayoutParams(new LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24)));
layout.addView(iv);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final AutomationEvent event = eventList.get(position);
holder.eventTitle.setText(event.getTitle());
holder.enabled.setChecked(event.isEnabled());
holder.iconLayout.removeAllViews();
// trigger icons
HashSet<Integer> triggerIcons = new HashSet<>();
TriggerConnector.fillIconSet((TriggerConnector) event.getTrigger(), triggerIcons);
for (int res : triggerIcons) {
addImage(res, holder.context, holder.iconLayout);
}
// arrow icon
ImageView iv = new ImageView(holder.context);
iv.setImageResource(R.drawable.ic_arrow_forward_white_24dp);
iv.setLayoutParams(new LinearLayout.LayoutParams(MainApp.dpToPx(24), MainApp.dpToPx(24)));
iv.setPadding(MainApp.dpToPx(4), 0, MainApp.dpToPx(4), 0);
holder.iconLayout.addView(iv);
// action icons
HashSet<Integer> actionIcons = new HashSet<>();
for (Action action : event.getActions()) {
if (action.icon().isPresent())
actionIcons.add(action.icon().get());
}
for (int res : actionIcons) {
addImage(res, holder.context, holder.iconLayout);
}
// enabled event
holder.enabled.setOnClickListener(v -> {
event.setEnabled((holder.enabled.isChecked()));
RxBus.Companion.getINSTANCE().send(new EventAutomationDataChanged());
});
// edit event
holder.rootLayout.setOnClickListener(v ->
{
//EditEventDialog dialog = EditEventDialog.Companion.newInstance(event, false);
EditEventDialog dialog = new EditEventDialog();
Bundle args = new Bundle();
args.putString("event", event.toJSON());
args.putInt("position", position);
dialog.setArguments(args);
if (fragmentManager != null)
dialog.show(fragmentManager, "EditEventDialog");
});
// Start a drag whenever the handle view it touched
holder.iconSort.setOnTouchListener((v, motionEvent) ->
{
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
mDragStartListener.onStartDrag(holder);
return true;
}
return v.onTouchEvent(motionEvent);
});
}
@Override
public int getItemCount() {
return eventList.size();
}
@Override
public boolean onItemMove(int fromPosition, int toPosition) {
Collections.swap(eventList, fromPosition, toPosition);
notifyItemMoved(fromPosition, toPosition);
RxBus.Companion.getINSTANCE().send(new EventAutomationDataChanged());
return true;
}
@Override
public void onItemDismiss(int position) {
OKDialog.showConfirmation(activity, MainApp.gs(R.string.removerecord) + " " + eventList.get(position).getTitle(),
() -> {
eventList.remove(position);
notifyItemRemoved(position);
RxBus.Companion.getINSTANCE().send(new EventAutomationDataChanged());
RxBus.Companion.getINSTANCE().send(new EventAutomationUpdateGui());
}, () -> {
RxBus.Companion.getINSTANCE().send(new EventAutomationUpdateGui());
});
}
static class ViewHolder extends RecyclerView.ViewHolder implements ItemTouchHelperViewHolder {
final RelativeLayout rootLayout;
final LinearLayout iconLayout;
final TextView eventTitle;
final Context context;
final ImageView iconSort;
final CheckBox enabled;
ViewHolder(View view, Context context) {
super(view);
this.context = context;
eventTitle = view.findViewById(R.id.viewEventTitle);
rootLayout = view.findViewById(R.id.rootLayout);
iconLayout = view.findViewById(R.id.iconLayout);
iconSort = view.findViewById(R.id.iconSort);
enabled = view.findViewById(R.id.automation_enabled);
}
@Override
public void onItemSelected() {
itemView.setBackgroundColor(Color.LTGRAY);
}
@Override
public void onItemClear() {
itemView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault));
}
}
}

View file

@ -1,107 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import android.widget.LinearLayout;
import com.google.common.base.Optional;
import org.json.JSONException;
import org.json.JSONObject;
import javax.annotation.Nullable;
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
import info.nightscout.androidaps.queue.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/*
Action ideas:
* cancel temp target
* change preference setting
* enable/disable plugin
* create notification
* create ugly alarm
* create profile switch
* set/cancel tbr
* set/cancel extended bolus
* run bolus wizard
Trigger ideas:
* location (close to)
* connected to specific wifi
* internet available/not available
* nsclient connected/disconnected
* iob
* cob
* autosens value
* delta, short delta, long delta
* last bolus ago
* is tbr running
* bolus wizard result
* loop is enabled, disabled, suspended, running
*/
public abstract class Action {
private static final Logger log = LoggerFactory.getLogger(Action.class);
public Trigger precondition = null;
public abstract int friendlyName();
public abstract String shortDescription();
public abstract void doAction(Callback callback);
public void generateDialog(LinearLayout root) {
}
public boolean hasDialog() {
return false;
}
public String toJSON() {
JSONObject o = new JSONObject();
try {
o.put("type", this.getClass().getName());
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
public abstract Optional<Integer> icon();
public Action fromJSON(String data) {
return this;
}
@Nullable
public static Action instantiate(JSONObject object) {
try {
String type = object.getString("type");
JSONObject data = object.optJSONObject("data");
Class clazz = Class.forName(type);
return ((Action) clazz.newInstance()).fromJSON(data != null ? data.toString() : "");
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | JSONException e) {
log.error("Unhandled exception", e);
}
return null;
}
public void apply(Action a) {
try {
JSONObject object = new JSONObject(a.toJSON());
String type = object.getString("type");
JSONObject data = object.getJSONObject("data");
if (type.equals(getClass().getName())) {
fromJSON(data.toString());
}
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
}
}

View file

@ -0,0 +1,78 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunction
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
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
abstract class Action(val mainApp: MainApp) {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var sp: SP
@Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var profileFunction: ProfileFunction
@Inject lateinit var resourceHelper: ResourceHelper
@Inject lateinit var configBuilderPlugin: ConfigBuilderPlugin
@Inject lateinit var loopPlugin: LoopPlugin
@Inject lateinit var treatmentsPlugin: TreatmentsPlugin
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin
var precondition: Trigger? = null
abstract fun friendlyName(): Int
abstract fun shortDescription(): String
abstract fun doAction(callback: Callback)
@DrawableRes abstract fun icon(): Int
init {
mainApp.androidInjector().inject(this)
}
open fun generateDialog(root: LinearLayout) {}
open fun hasDialog(): Boolean = false
open fun toJSON(): String =
JSONObject().put("type", this.javaClass.name).toString()
open fun fromJSON(data: String): Action = this
fun apply(a: Action) {
val obj = JSONObject(a.toJSON())
val type = obj.getString("type")
val data = obj.getJSONObject("data")
if (type == javaClass.name) fromJSON(data.toString())
}
fun instantiate(obj: JSONObject): Action? {
try {
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.newInstance() as Action).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
}
}

View file

@ -0,0 +1,24 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.queue.Callback
// Used for instantiation of other actions only
class ActionDummy(mainApp: MainApp) : Action(mainApp) {
override fun friendlyName(): Int {
throw NotImplementedError("An operation is not implemented")
}
override fun shortDescription(): String {
throw NotImplementedError("An operation is not implemented")
}
override fun doAction(callback: Callback) {
throw NotImplementedError("An operation is not implemented")
}
override fun icon(): Int {
throw NotImplementedError("An operation is not implemented")
}
}

View file

@ -1,49 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import com.google.common.base.Optional;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.Callback;
public class ActionLoopDisable extends Action {
@Override
public int friendlyName() {
return R.string.disableloop;
}
@Override
public String shortDescription() {
return MainApp.gs(R.string.disableloop);
}
@Override
public void doAction(Callback callback) {
if (LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) {
LoopPlugin.getPlugin().setPluginEnabled(PluginType.LOOP, false);
ConfigBuilderPlugin.getPlugin().storeSettings("ActionLoopDisable");
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, new Callback() {
@Override
public void run() {
RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("ActionLoopDisable"));
if (callback != null)
callback.result(result).run();
}
});
} else {
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.alreadydisabled)).run();
}
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.ic_stop_24dp);
}
}

View file

@ -0,0 +1,31 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventRefreshOverview
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.queue.Callback
class ActionLoopDisable(mainApp: MainApp) : Action(mainApp) {
override fun friendlyName(): Int = R.string.disableloop
override fun shortDescription(): String = resourceHelper.gs(R.string.disableloop)
@DrawableRes override fun icon(): Int = R.drawable.ic_stop_24dp
override fun doAction(callback: Callback) {
if (loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.setPluginEnabled(PluginType.LOOP, false)
configBuilderPlugin.storeSettings("ActionLoopDisable")
configBuilderPlugin.commandQueue.cancelTempBasal(true, object : Callback() {
override fun run() {
rxBus.send(EventRefreshOverview("ActionLoopDisable"))
callback.result(result).run()
}
})
} else {
callback.result(PumpEnactResult().success(true).comment(R.string.alreadydisabled)).run()
}
}
}

View file

@ -1,44 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import com.google.common.base.Optional;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.queue.Callback;
public class ActionLoopEnable extends Action {
@Override
public int friendlyName() {
return R.string.enableloop;
}
@Override
public String shortDescription() {
return MainApp.gs(R.string.enableloop);
}
@Override
public void doAction(Callback callback) {
if (!LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) {
LoopPlugin.getPlugin().setPluginEnabled(PluginType.LOOP, true);
ConfigBuilderPlugin.getPlugin().storeSettings("ActionLoopEnable");
RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("ActionLoopEnable"));
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
} else {
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.alreadyenabled)).run();
}
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.ic_play_circle_outline_24dp);
}
}

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventRefreshOverview
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.queue.Callback
class ActionLoopEnable(mainApp: MainApp) : Action(mainApp) {
override fun friendlyName(): Int = R.string.enableloop
override fun shortDescription(): String = resourceHelper.gs(R.string.enableloop)
@DrawableRes override fun icon(): Int = R.drawable.ic_play_circle_outline_24dp
override fun doAction(callback: Callback) {
if (!loopPlugin.isEnabled(PluginType.LOOP)) {
loopPlugin.setPluginEnabled(PluginType.LOOP, true)
configBuilderPlugin.storeSettings("ActionLoopEnable")
rxBus.send(EventRefreshOverview("ActionLoopEnable"))
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
} else {
callback.result(PumpEnactResult().success(true).comment(R.string.alreadyenabled))?.run()
}
}
}

View file

@ -1,45 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import com.google.common.base.Optional;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.queue.Callback;
public class ActionLoopResume extends Action {
@Override
public int friendlyName() {
return R.string.resumeloop;
}
@Override
public String shortDescription() {
return MainApp.gs(R.string.resumeloop);
}
@Override
public void doAction(Callback callback) {
if (LoopPlugin.getPlugin().isSuspended()) {
LoopPlugin.getPlugin().suspendTo(0);
ConfigBuilderPlugin.getPlugin().storeSettings("ActionLoopResume");
NSUpload.uploadOpenAPSOffline(0);
RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("ActionLoopResume"));
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
} else {
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.notsuspended)).run();
}
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.ic_replay_24dp);
}
}

View file

@ -0,0 +1,28 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventRefreshOverview
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.queue.Callback
class ActionLoopResume(mainApp: MainApp) : Action(mainApp) {
override fun friendlyName(): Int = R.string.resumeloop
override fun shortDescription(): String = resourceHelper.gs(R.string.resumeloop)
@DrawableRes override fun icon(): Int = R.drawable.ic_replay_24dp
override fun doAction(callback: Callback) {
if (loopPlugin.isSuspended) {
loopPlugin.suspendTo(0)
configBuilderPlugin.storeSettings("ActionLoopResume")
NSUpload.uploadOpenAPSOffline(0.0)
rxBus.send(EventRefreshOverview("ActionLoopResume"))
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
} else {
callback.result(PumpEnactResult().success(true).comment(R.string.notsuspended))?.run()
}
}
}

View file

@ -1,95 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import android.widget.LinearLayout;
import com.google.common.base.Optional;
import org.json.JSONException;
import org.json.JSONObject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus;
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.queue.Callback;
import info.nightscout.androidaps.utils.JsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ActionLoopSuspend extends Action {
private static final Logger log = LoggerFactory.getLogger(ActionLoopSuspend.class);
public InputDuration minutes = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
@Override
public int friendlyName() {
return R.string.suspendloop;
}
@Override
public String shortDescription() {
return MainApp.gs(R.string.suspendloopforXmin, minutes.getMinutes());
}
@Override
public void doAction(Callback callback) {
if (!LoopPlugin.getPlugin().isSuspended()) {
LoopPlugin.getPlugin().suspendLoop(minutes.getMinutes());
RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("ActionLoopSuspend"));
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
} else {
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.alreadysuspended)).run();
}
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.ic_pause_circle_outline_24dp);
}
@Override
public String toJSON() {
JSONObject o = new JSONObject();
JSONObject data = new JSONObject();
try {
data.put("minutes", minutes.getMinutes());
o.put("type", this.getClass().getName());
o.put("data", data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
@Override
public Action fromJSON(String data) {
try {
JSONObject o = new JSONObject(data);
minutes.setMinutes(JsonHelper.safeGetInt(o, "minutes"));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return this;
}
@Override
public boolean hasDialog() {
return true;
}
@Override
public void generateDialog(LinearLayout root) {
new LayoutBuilder()
.add(new LabelWithElement(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "", minutes))
.build(root);
}
}

View file

@ -0,0 +1,54 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventRefreshOverview
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.queue.Callback
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
class ActionLoopSuspend(mainApp: MainApp) : Action(mainApp) {
var minutes = InputDuration(0, InputDuration.TimeUnit.MINUTES)
override fun friendlyName(): Int = R.string.suspendloop
override fun shortDescription(): String = resourceHelper.gs(R.string.suspendloopforXmin, minutes.minutes)
@DrawableRes override fun icon(): Int = R.drawable.ic_pause_circle_outline_24dp
override fun doAction(callback: Callback) {
if (!loopPlugin.isSuspended) {
loopPlugin.suspendLoop(minutes.minutes)
rxBus.send(EventRefreshOverview("ActionLoopSuspend"))
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
} else {
callback.result(PumpEnactResult().success(true).comment(R.string.alreadysuspended))?.run()
}
}
override fun toJSON(): String {
val data = JSONObject().put("minutes", minutes.minutes)
return JSONObject()
.put("type", this.javaClass.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Action {
val o = JSONObject(data)
minutes.minutes = JsonHelper.safeGetInt(o, "minutes")
return this
}
override fun hasDialog(): Boolean = true
override fun generateDialog(root: LinearLayout) {
LayoutBuilder()
.add(LabelWithElement(resourceHelper.gs(R.string.careportal_newnstreatment_duration_min_label), "", minutes))
.build(root)
}
}

View file

@ -1,95 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import android.widget.LinearLayout;
import com.google.common.base.Optional;
import org.json.JSONException;
import org.json.JSONObject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.plugins.bus.RxBus;
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.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.JsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ActionNotification extends Action {
private static final Logger log = LoggerFactory.getLogger(ActionNotification.class);
public InputString text = new InputString();
@Override
public int friendlyName() {
return R.string.notification;
}
@Override
public String shortDescription() {
return MainApp.gs(R.string.notification_message, text.getValue());
}
@Override
public void doAction(Callback callback) {
Notification notification = new Notification(Notification.USERMESSAGE, text.getValue(), Notification.URGENT);
RxBus.Companion.getINSTANCE().send(new EventNewNotification(notification));
NSUpload.uploadError(text.getValue());
RxBus.Companion.getINSTANCE().send(new EventRefreshOverview("ActionNotification"));
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.ic_notifications);
}
@Override
public String toJSON() {
JSONObject o = new JSONObject();
JSONObject data = new JSONObject();
try {
data.put("text", text.getValue());
o.put("type", this.getClass().getName());
o.put("data", data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
@Override
public Action fromJSON(String data) {
try {
JSONObject o = new JSONObject(data);
text.setValue(JsonHelper.safeGetString(o, "text"));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return this;
}
@Override
public boolean hasDialog() {
return true;
}
@Override
public void generateDialog(LinearLayout root) {
new LayoutBuilder()
.add(new LabelWithElement(MainApp.gs(R.string.message_short), "", text))
.build(root);
}
}

View file

@ -0,0 +1,55 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.events.EventRefreshOverview
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.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
class ActionNotification(mainApp: MainApp) : Action(mainApp) {
var text = InputString()
override fun friendlyName(): Int = R.string.notification
override fun shortDescription(): String = resourceHelper.gs(R.string.notification_message, text.value)
@DrawableRes override fun icon(): Int = R.drawable.ic_notifications
override fun doAction(callback: Callback) {
val notification = Notification(Notification.USERMESSAGE, text.value, Notification.URGENT)
rxBus.send(EventNewNotification(notification))
NSUpload.uploadError(text.value)
rxBus.send(EventRefreshOverview("ActionNotification"))
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
}
override fun toJSON(): String {
val data = JSONObject().put("text", text.value)
return JSONObject()
.put("type", this.javaClass.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Action {
val o = JSONObject(data)
text.value = JsonHelper.safeGetString(o, "text")
return this
}
override fun hasDialog(): Boolean = true
override fun generateDialog(root: LinearLayout) {
LayoutBuilder()
.add(LabelWithElement(resourceHelper.gs(R.string.message_short), "", text))
.build(root)
}
}

View file

@ -1,151 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import android.widget.LinearLayout;
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.ProfileStore;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.automation.elements.InputProfileName;
import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement;
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.JsonHelper;
public class ActionProfileSwitch extends Action {
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
InputProfileName inputProfileName;
String profileName = "";
public ActionProfileSwitch() {
// Prevent action if active profile is already active
// but we don't have a trigger IS_NOT_EQUAL
// so check is in the doRun()
ProfileInterface profileInterface = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
if (profileInterface != null) {
ProfileStore profileStore = profileInterface.getProfile();
if (profileStore != null) {
String name = profileStore.getDefaultProfileName();
if (name != null) {
profileName = name;
}
}
}
inputProfileName = new InputProfileName(profileName);
}
@Override
public int friendlyName() {
return R.string.profilename;
}
@Override
public String shortDescription() {
String returned = MainApp.gs(R.string.changengetoprofilename, inputProfileName.getValue());
return returned;
}
@Override
public void doAction(Callback callback) {
String activeProfileName = ProfileFunctions.getInstance().getProfileName();
//Check for uninitialized profileName
if (profileName.equals("")) {
log.error("Selected profile not initialized");
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.error_field_must_not_be_empty)).run();
return;
}
if (ProfileFunctions.getInstance().getProfile() == null) {
log.error("ProfileFunctions not initialized");
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.noprofile)).run();
return;
}
if (profileName.equals(activeProfileName)) {
if (L.isEnabled(L.AUTOMATION))
log.debug("Profile is already switched");
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.alreadyset)).run();
return;
}
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
if (activeProfile == null) {
log.error("ProfileInterface not initialized");
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.noprofile)).run();
return;
}
ProfileStore profileStore = activeProfile.getProfile();
if (profileStore == null) return;
if (profileStore.getSpecificProfile(profileName) == null) {
if (L.isEnabled(L.AUTOMATION))
log.error("Selected profile does not exist! - " + profileName);
if (callback != null)
callback.result(new PumpEnactResult().success(false).comment(R.string.notexists)).run();
return;
}
TreatmentsPlugin.getPlugin().doProfileSwitch(profileStore, profileName, 0, 100, 0, DateUtil.now());
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
}
@Override
public void generateDialog(LinearLayout root) {
new LayoutBuilder()
.add(new LabelWithElement(MainApp.gs(R.string.profilename), "", inputProfileName))
.build(root);
}
@Override
public boolean hasDialog() {
return true;
}
@Override
public String toJSON() {
JSONObject o = new JSONObject();
try {
o.put("type", ActionProfileSwitch.class.getName());
JSONObject data = new JSONObject();
data.put("profileToSwitchTo", inputProfileName.getValue());
o.put("data", data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
@Override
public Action fromJSON(String data) {
try {
JSONObject d = new JSONObject(data);
profileName = JsonHelper.safeGetString(d, "profileToSwitchTo");
inputProfileName.setValue(profileName);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return this;
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.icon_actions_profileswitch);
}
}

View file

@ -0,0 +1,73 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.general.automation.elements.InputProfileName
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.DateUtil
import info.nightscout.androidaps.utils.JsonHelper
import org.json.JSONObject
class ActionProfileSwitch(mainApp: MainApp) : Action(mainApp) {
var inputProfileName: InputProfileName = InputProfileName("")
override fun friendlyName(): Int = R.string.profilename
override fun shortDescription(): String = resourceHelper.gs(R.string.changengetoprofilename, inputProfileName.value)
@DrawableRes override fun icon(): Int = R.drawable.icon_actions_profileswitch
override fun doAction(callback: Callback) {
val activeProfileName = profileFunction.getProfileName()
//Check for uninitialized profileName
if (inputProfileName.value == "") {
aapsLogger.error(LTag.AUTOMATION, "Selected profile not initialized")
callback.result(PumpEnactResult().success(false).comment(R.string.error_field_must_not_be_empty))?.run()
return
}
if (profileFunction.getProfile() == null) {
aapsLogger.error(LTag.AUTOMATION, "ProfileFunctions not initialized")
callback.result(PumpEnactResult().success(false).comment(R.string.noprofile))?.run()
return
}
if (inputProfileName.value == activeProfileName) {
aapsLogger.debug(LTag.AUTOMATION, "Profile is already switched")
callback.result(PumpEnactResult().success(true).comment(R.string.alreadyset))?.run()
return
}
val profileStore = configBuilderPlugin.activeProfileInterface.profile ?: return
if (profileStore.getSpecificProfile(inputProfileName.value) == null) {
aapsLogger.error(LTag.AUTOMATION, "Selected profile does not exist! - ${inputProfileName.value}")
callback.result(PumpEnactResult().success(false).comment(R.string.notexists))?.run()
return
}
treatmentsPlugin.doProfileSwitch(profileStore, inputProfileName.value, 0, 100, 0, DateUtil.now())
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
}
override fun generateDialog(root: LinearLayout) {
LayoutBuilder()
.add(LabelWithElement(resourceHelper.gs(R.string.profilename), "", inputProfileName))
.build(root)
}
override fun hasDialog(): Boolean = true
override fun toJSON(): String {
val data = JSONObject().put("profileToSwitchTo", inputProfileName.value)
return JSONObject()
.put("type", this.javaClass.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Action {
val o = JSONObject(data)
inputProfileName.value = JsonHelper.safeGetString(o, "profileToSwitchTo")
return this
}
}

View file

@ -1,99 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import android.widget.LinearLayout;
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.PumpEnactResult;
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.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.triggers.TriggerProfilePercent;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.JsonHelper;
public class ActionProfileSwitchPercent extends Action {
private static final Logger log = LoggerFactory.getLogger(ActionProfileSwitchPercent.class);
InputPercent pct = new InputPercent();
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
public ActionProfileSwitchPercent() {
precondition = new TriggerProfilePercent().comparator(Comparator.Compare.IS_EQUAL).setValue(100);
}
@Override
public int friendlyName() {
return R.string.profilepercentage;
}
@Override
public String shortDescription() {
if (duration.getMinutes() == 0)
return MainApp.gs(R.string.startprofileforever, (int) pct.getValue());
else
return MainApp.gs(R.string.startprofile, (int) pct.getValue(), duration.getMinutes());
}
@Override
public void doAction(Callback callback) {
TreatmentsPlugin.getPlugin().doProfileSwitch((int) duration.getValue(), (int) pct.getValue(), 0);
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
}
@Override
public void generateDialog(LinearLayout root) {
new LayoutBuilder()
.add(new LabelWithElement(MainApp.gs(R.string.percent_u), "", pct))
.add(new LabelWithElement(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
.build(root);
}
@Override
public boolean hasDialog() {
return true;
}
@Override
public String toJSON() {
JSONObject o = new JSONObject();
try {
o.put("type", ActionProfileSwitchPercent.class.getName());
JSONObject data = new JSONObject();
data.put("percentage", pct.getValue());
data.put("durationInMinutes", duration.getMinutes());
o.put("data", data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
@Override
public Action fromJSON(String data) {
try {
JSONObject d = new JSONObject(data);
pct.setValue(JsonHelper.safeGetInt(d, "percentage"));
duration.setMinutes(JsonHelper.safeGetInt(d, "durationInMinutes"));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return this;
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.icon_actions_profileswitch);
}
}

View file

@ -0,0 +1,63 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
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.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.triggers.TriggerProfilePercent
import info.nightscout.androidaps.queue.Callback
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)
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)
@DrawableRes override fun icon(): Int = R.drawable.icon_actions_profileswitch
init {
precondition = TriggerProfilePercent().comparator(Comparator.Compare.IS_EQUAL).setValue(100.0)
}
override fun doAction(callback: Callback) {
treatmentsPlugin.doProfileSwitch(duration.value.toInt(), 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))
.build(root)
}
override fun hasDialog(): Boolean = true
override fun toJSON(): String {
val data = JSONObject()
.put("percentage", pct.value)
.put("durationInMinutes", duration.minutes)
return JSONObject()
.put("type", this.javaClass.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Action {
val o = JSONObject(data)
pct.value = JsonHelper.safeGetDouble(o, "percentage")
duration.minutes = JsonHelper.safeGetInt(o, "durationInMinutes")
return this
}
}

View file

@ -1,98 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import android.widget.LinearLayout;
import com.google.common.base.Optional;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
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.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.JsonHelper;
public class ActionSendSMS extends Action {
private static final Logger log = LoggerFactory.getLogger(ActionSendSMS.class);
public InputString text = new InputString();
@Inject
SmsCommunicatorPlugin smsCommunicatorPlugin;
public ActionSendSMS() {
super();
MainApp.instance().androidInjector().inject(this); // TODO inject or pass itno constructor once AutomationPlugin is prepared for Dagger
}
@Override
public int friendlyName() {
return R.string.sendsmsactiondescription;
}
@Override
public String shortDescription() {
return MainApp.gs(R.string.sendsmsactionlabel, text.getValue());
}
@Override
public void doAction(Callback callback) {
boolean result = smsCommunicatorPlugin.sendNotificationToAllNumbers(text.getValue());
if (callback != null)
callback.result(new PumpEnactResult().success(result).comment(result ? R.string.ok : R.string.danar_error)).run();
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.ic_notifications);
}
@Override
public String toJSON() {
JSONObject o = new JSONObject();
JSONObject data = new JSONObject();
try {
data.put("text", text.getValue());
o.put("type", this.getClass().getName());
o.put("data", data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
@Override
public Action fromJSON(String data) {
try {
JSONObject o = new JSONObject(data);
text.setValue(JsonHelper.safeGetString(o, "text"));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return this;
}
@Override
public boolean hasDialog() {
return true;
}
@Override
public void generateDialog(LinearLayout root) {
new LayoutBuilder()
.add(new LabelWithElement(MainApp.gs(R.string.sendsmsactiontext), "", text))
.build(root);
}
}

View file

@ -0,0 +1,47 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import android.widget.LinearLayout
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
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.queue.Callback
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import org.json.JSONObject
class ActionSendSMS(mainApp: MainApp) : Action(mainApp) {
var text = InputString()
override fun friendlyName(): Int = R.string.sendsmsactiondescription
override fun shortDescription(): String = resourceHelper.gs(R.string.sendsmsactionlabel, text.value)
override fun icon(): Int = R.drawable.ic_notifications
override fun doAction(callback: Callback) {
val result = smsCommunicatorPlugin.sendNotificationToAllNumbers(text.value)
callback.result(PumpEnactResult().success(result).comment(if (result) R.string.ok else R.string.danar_error))?.run()
}
override fun toJSON(): String {
val data = JSONObject().put("text", text.value)
return JSONObject()
.put("type", this.javaClass.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Action {
val o = JSONObject(data)
text.value = safeGetString(o, "text")
return this
}
override fun hasDialog(): Boolean = true
override fun generateDialog(root: LinearLayout) {
LayoutBuilder()
.add(LabelWithElement(resourceHelper.gs(R.string.sendsmsactiontext), "", text))
.build(root)
}
}

View file

@ -1,123 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import android.widget.LinearLayout;
import com.google.common.base.Optional;
import org.json.JSONException;
import org.json.JSONObject;
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.data.PumpEnactResult;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists;
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration;
import info.nightscout.androidaps.plugins.general.automation.elements.InputTempTarget;
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.triggers.TriggerTempTarget;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.JsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ActionStartTempTarget extends Action {
private static final Logger log = LoggerFactory.getLogger(ActionStartTempTarget.class);
String reason = "";
InputTempTarget value = new InputTempTarget();
InputDuration duration = new InputDuration(0, InputDuration.TimeUnit.MINUTES);
private TempTarget tempTarget;
public ActionStartTempTarget() {
precondition = new TriggerTempTarget().comparator(ComparatorExists.Compare.NOT_EXISTS);
}
@Override
public int friendlyName() {
return R.string.starttemptarget;
}
@Override
public String shortDescription() {
tempTarget = new TempTarget()
.date(DateUtil.now())
.duration(duration.getMinutes())
.reason(reason)
.source(Source.USER)
.low(Profile.toMgdl(value.getValue(), value.getUnits()))
.high(Profile.toMgdl(value.getValue(), value.getUnits()));
return MainApp.gs(R.string.starttemptarget) + ": " + (tempTarget == null ? "null" : tempTarget.friendlyDescription(value.getUnits()));
}
@Override
public void doAction(Callback callback) {
tempTarget = new TempTarget()
.date(DateUtil.now())
.duration(duration.getMinutes())
.reason(reason)
.source(Source.USER)
.low(Profile.toMgdl(value.getValue(), value.getUnits()))
.high(Profile.toMgdl(value.getValue(), value.getUnits()));
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
}
@Override
public void generateDialog(LinearLayout root) {
int unitResId = value.getUnits().equals(Constants.MGDL) ? R.string.mgdl : R.string.mmol;
new LayoutBuilder()
.add(new LabelWithElement(MainApp.gs(R.string.careportal_temporarytarget) + "\n[" + MainApp.gs(unitResId) + "]", "", value))
.add(new LabelWithElement(MainApp.gs(R.string.careportal_newnstreatment_duration_min_label), "", duration))
.build(root);
}
@Override
public boolean hasDialog() {
return true;
}
@Override
public String toJSON() {
JSONObject o = new JSONObject();
try {
o.put("type", ActionStartTempTarget.class.getName());
JSONObject data = new JSONObject();
data.put("reason", reason);
data.put("value", value.getValue());
data.put("units", value.getUnits());
data.put("durationInMinutes", duration.getMinutes());
o.put("data", data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
@Override
public Action fromJSON(String data) {
try {
JSONObject d = new JSONObject(data);
reason = JsonHelper.safeGetString(d, "reason");
value.setUnits(JsonHelper.safeGetString(d, "units"));
value.setValue(JsonHelper.safeGetDouble(d, "value"));
duration.setMinutes(JsonHelper.safeGetInt(d, "durationInMinutes"));
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return this;
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.icon_cp_cgm_target);
}
}

View file

@ -0,0 +1,81 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import android.widget.LinearLayout
import androidx.annotation.DrawableRes
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.data.PumpEnactResult
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TempTarget
import info.nightscout.androidaps.plugins.general.automation.elements.ComparatorExists
import info.nightscout.androidaps.plugins.general.automation.elements.InputDuration
import info.nightscout.androidaps.plugins.general.automation.elements.InputTempTarget
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.triggers.TriggerTempTarget
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.DateUtil
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)
init {
precondition = TriggerTempTarget().comparator(ComparatorExists.Compare.NOT_EXISTS)
}
override fun friendlyName(): Int = R.string.starttemptarget
override fun shortDescription(): String = resourceHelper.gs(R.string.starttemptarget) + ": " + tt().friendlyDescription(value.units)
@DrawableRes override fun icon(): Int = R.drawable.icon_cp_cgm_target
override fun doAction(callback: Callback) {
treatmentsPlugin.addToHistoryTempTarget(tt())
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
}
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))
.build(root)
}
override fun hasDialog(): Boolean {
return true
}
override fun toJSON(): String {
val data = JSONObject()
.put("value", value.value)
.put("units", value.units)
.put("durationInMinutes", duration.minutes)
return JSONObject()
.put("type", this.javaClass.name)
.put("data", data)
.toString()
}
override fun fromJSON(data: String): Action {
val o = JSONObject(data)
value.units = safeGetString(o, "units")
value.value = safeGetDouble(o, "value")
duration.minutes = safeGetInt(o, "durationInMinutes")
return this
}
fun tt(): TempTarget =
TempTarget()
.date(DateUtil.now())
.duration(duration.minutes)
.reason("Automation")
.source(Source.USER)
.low(Profile.toMgdl(value.value, value.units))
.high(Profile.toMgdl(value.value, value.units))
}

View file

@ -1,81 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.actions;
import com.google.common.base.Optional;
import org.json.JSONException;
import org.json.JSONObject;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.db.Source;
import info.nightscout.androidaps.db.TempTarget;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.JsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ActionStopTempTarget extends Action {
private static final Logger log = LoggerFactory.getLogger(ActionStopTempTarget.class);
String reason = "";
private TempTarget tempTarget;
public ActionStopTempTarget() {
}
@Override
public int friendlyName() {
return R.string.stoptemptarget;
}
@Override
public String shortDescription() {
return MainApp.gs(R.string.stoptemptarget);
}
@Override
public void doAction(Callback callback) {
tempTarget = new TempTarget().date(DateUtil.now()).duration(0).reason(reason).source(Source.USER).low(0).high(0);
TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget);
if (callback != null)
callback.result(new PumpEnactResult().success(true).comment(R.string.ok)).run();
}
@Override
public boolean hasDialog() {
return false;
}
@Override
public String toJSON() {
JSONObject o = new JSONObject();
try {
o.put("type", ActionStopTempTarget.class.getName());
JSONObject data = new JSONObject();
data.put("reason", reason);
o.put("data", data);
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return o.toString();
}
@Override
public Action fromJSON(String data) {
try {
JSONObject d = new JSONObject(data);
reason = JsonHelper.safeGetString(d, "reason");
} catch (JSONException e) {
log.error("Unhandled exception", e);
}
return this;
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.ic_stop_24dp);
}
}

View file

@ -0,0 +1,27 @@
package info.nightscout.androidaps.plugins.general.automation.actions
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.db.TempTarget
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.DateUtil
class ActionStopTempTarget(mainApp: MainApp) : Action(mainApp) {
override fun friendlyName(): Int = R.string.stoptemptarget
override fun shortDescription(): String = resourceHelper.gs(R.string.stoptemptarget)
override fun icon(): Int = R.drawable.ic_stop_24dp
override fun doAction(callback: Callback) {
val tempTarget = TempTarget()
.date(DateUtil.now())
.duration(0)
.reason("Automation")
.source(Source.USER)
.low(0.0).high(0.0)
treatmentsPlugin.addToHistoryTempTarget(tempTarget)
callback.result(PumpEnactResult().success(true).comment(R.string.ok))?.run()
}
}

View file

@ -1,56 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.dialogs
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.fragment.app.FragmentManager
import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.actions.Action
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
class ActionListAdapter(private val fragmentManager: FragmentManager, private val actionList: MutableList<Action>)
: RecyclerView.Adapter<ActionListAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.automation_action_item, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val action = actionList[position]
holder.bind(action, fragmentManager, this, position, actionList)
}
override fun getItemCount(): Int {
return actionList.size
}
class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
fun bind(action: Action, fragmentManager: FragmentManager, recyclerView: RecyclerView.Adapter<ViewHolder>, position: Int, actionList: MutableList<Action>) {
view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener {
if (action.hasDialog()) {
val args = Bundle()
args.putInt("actionPosition", position)
args.putString("action", action.toJSON())
val dialog = EditActionDialog()
dialog.arguments = args
dialog.show(fragmentManager, "EditActionDialog")
}
}
view.findViewById<ImageView>(R.id.automation_iconTrash).setOnClickListener {
actionList.remove(action)
recyclerView.notifyDataSetChanged()
RxBus.INSTANCE.send(EventAutomationUpdateGui())
}
if (action.icon().isPresent) view.findViewById<ImageView>(R.id.automation_action_image).setImageResource(action.icon().get())
view.findViewById<TextView>(R.id.automation_viewActionTitle).text = action.shortDescription()
}
}
}

View file

@ -4,10 +4,12 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.actions.Action 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.events.EventAutomationUpdateAction import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction
import kotlinx.android.synthetic.main.automation_dialog_action.* import kotlinx.android.synthetic.main.automation_dialog_action.*
import org.json.JSONObject import org.json.JSONObject
@ -15,6 +17,7 @@ import javax.inject.Inject
class EditActionDialog : DialogFragmentWithDate() { class EditActionDialog : DialogFragmentWithDate() {
@Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var rxBus: RxBusWrapper
@Inject lateinit var mainApp: MainApp
private var action: Action? = null private var action: Action? = null
private var actionPosition: Int = -1 private var actionPosition: Int = -1
@ -24,7 +27,7 @@ class EditActionDialog : DialogFragmentWithDate() {
// load data from bundle // load data from bundle
(savedInstanceState ?: arguments)?.let { bundle -> (savedInstanceState ?: arguments)?.let { bundle ->
actionPosition = bundle.getInt("actionPosition", -1) actionPosition = bundle.getInt("actionPosition", -1)
bundle.getString("action")?.let { action = Action.instantiate(JSONObject(it)) } bundle.getString("action")?.let { action = ActionDummy(mainApp).instantiate(JSONObject(it)) }
} }
onCreateViewGeneral() onCreateViewGeneral()
return inflater.inflate(R.layout.automation_dialog_action, container, false) return inflater.inflate(R.layout.automation_dialog_action, container, false)

View file

@ -4,12 +4,17 @@ import android.os.Bundle
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.dialogs.DialogFragmentWithDate import info.nightscout.androidaps.dialogs.DialogFragmentWithDate
import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.automation.actions.Action
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationAddAction
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateAction
@ -61,7 +66,7 @@ class EditEventDialog : DialogFragmentWithDate() {
} }
// setup action list view // setup action list view
fragmentManager?.let { actionListAdapter = ActionListAdapter(it, event.actions) } fragmentManager?.let { actionListAdapter = ActionListAdapter() }
automation_actionListView.layoutManager = LinearLayoutManager(context) automation_actionListView.layoutManager = LinearLayoutManager(context)
automation_actionListView.adapter = actionListAdapter automation_actionListView.adapter = actionListAdapter
@ -161,4 +166,44 @@ class EditEventDialog : DialogFragmentWithDate() {
automation_forcedTriggerDescriptionLabel.visibility = View.GONE automation_forcedTriggerDescriptionLabel.visibility = View.GONE
} }
} }
inner class ActionListAdapter : RecyclerView.Adapter<ActionListAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val v = LayoutInflater.from(parent.context).inflate(R.layout.automation_action_item, parent, false)
return ViewHolder(v)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val action = event.actions[position]
holder.bind(action, this, position)
}
override fun getItemCount(): Int = event.actions.size
inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
fun bind(action: Action, recyclerView: RecyclerView.Adapter<ViewHolder>, position: Int) {
view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener {
if (action.hasDialog()) {
val args = Bundle()
args.putInt("actionPosition", position)
args.putString("action", action.toJSON())
val dialog = EditActionDialog()
dialog.arguments = args
fragmentManager?.let {
dialog.show(it, "EditActionDialog")
}
}
}
view.findViewById<ImageView>(R.id.automation_iconTrash).setOnClickListener {
event.actions.remove(action)
recyclerView.notifyDataSetChanged()
rxBus.send(EventAutomationUpdateGui())
}
view.findViewById<ImageView>(R.id.automation_action_image).setImageResource(action.icon())
view.findViewById<TextView>(R.id.automation_viewActionTitle).text = action.shortDescription()
}
}
}
} }

View file

@ -1,31 +1,10 @@
package info.nightscout.androidaps.utils package info.nightscout.androidaps.utils
import org.json.JSONArray
import org.json.JSONException import org.json.JSONException
import org.json.JSONObject import org.json.JSONObject
object JsonHelper { object JsonHelper {
@JvmStatic
fun createJSONObject(s : String?) : JSONObject? {
var result : JSONObject? = null
try {
result = JSONObject(s)
} catch (ignored: JSONException) {
}
return result
}
@JvmStatic
fun createJSONArray(s : String?) : JSONArray? {
var result : JSONArray? = null
try {
result = JSONArray(s)
} catch (ignored: JSONException) {
}
return result
}
@JvmStatic @JvmStatic
fun safeGetObject(json: JSONObject?, fieldName: String, defaultValue: Any): Any { fun safeGetObject(json: JSONObject?, fieldName: String, defaultValue: Any): Any {
var result = defaultValue var result = defaultValue