migrate to kotlin, remove butterknife, code claeanup

This commit is contained in:
Milos Kozak 2019-07-18 23:49:59 +02:00
parent 1c8aae9757
commit d25f6f07b0
35 changed files with 640 additions and 820 deletions

View file

@ -209,7 +209,7 @@ public class MainApp extends Application {
pluginsList.add(TidepoolPlugin.INSTANCE);
pluginsList.add(MaintenancePlugin.initPlugin(this));
if (engineeringMode)
pluginsList.add(AutomationPlugin.getPlugin());
pluginsList.add(AutomationPlugin.INSTANCE);
pluginsList.add(ConfigBuilderPlugin.getPlugin());

View file

@ -189,7 +189,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(AutomationPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResource(R.xml.pref_others);
addPreferencesFromResource(R.xml.pref_datachoices);

View file

@ -1,85 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.squareup.otto.Subscribe;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.common.SubscriberFragment;
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
public class AutomationFragment extends SubscriberFragment {
@BindView(R.id.eventListView)
RecyclerView mEventListView;
@BindView(R.id.logView)
TextView mLogView;
private EventListAdapter mEventListAdapter;
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.automation_fragment, container, false);
unbinder = ButterKnife.bind(this, view);
final AutomationPlugin plugin = AutomationPlugin.getPlugin();
mEventListAdapter = new EventListAdapter(plugin.getAutomationEvents(), getFragmentManager());
mEventListView.setLayoutManager(new LinearLayoutManager(getContext()));
mEventListView.setAdapter(mEventListAdapter);
return view;
}
@Subscribe
public void onEvent(EventAutomationUpdateGui unused) {
updateGUI();
}
@Subscribe
public void onEvent(EventAutomationDataChanged unused) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(() -> {
mEventListAdapter.notifyDataSetChanged();
});
}
@Override
public void updateGUI() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(() -> {
mEventListAdapter.notifyDataSetChanged();
StringBuilder sb = new StringBuilder();
for (String l : AutomationPlugin.getPlugin().executionLog) {
sb.append(l);
sb.append("\n");
}
mLogView.setText(sb.toString());
});
}
@OnClick(R.id.fabAddEvent)
void onClickAddEvent(View unused) {
EditEventDialog dialog = EditEventDialog.newInstance(new AutomationEvent(), true);
if (getFragmentManager() != null)
dialog.show(getFragmentManager(), "EditEventDialog");
}
}

View file

@ -0,0 +1,73 @@
package info.nightscout.androidaps.plugins.general.automation
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.dialogs.EditEventDialog
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import kotlinx.android.synthetic.main.automation_fragment.*
class AutomationFragment : Fragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
private var eventListAdapter: EventListAdapter? = null
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
add(disposable)
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.automation_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
eventListAdapter = EventListAdapter(AutomationPlugin.automationEvents, fragmentManager)
automation_eventListView.layoutManager = LinearLayoutManager(context)
automation_eventListView.adapter = eventListAdapter
automation_fabAddEvent.setOnClickListener {
val dialog = EditEventDialog()
val args = Bundle()
args.putString("event", AutomationEvent().toJSON())
args.putInt("position", -1) // New event
dialog.arguments = args
fragmentManager?.let { dialog.show(it, "EditEventDialog") }
}
disposable += RxBus
.toObservable(EventAutomationUpdateGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
eventListAdapter?.notifyDataSetChanged()
val sb = StringBuilder()
for (l in AutomationPlugin.executionLog) {
sb.append(l)
sb.append("\n")
}
automation_logView.text = sb.toString()
}, {})
disposable += RxBus
.toObservable(EventAutomationDataChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
eventListAdapter?.notifyDataSetChanged()
}, {})
}
override fun onStop() {
super.onStop()
disposable.clear()
}
}

View file

@ -1,234 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import com.squareup.otto.Subscribe;
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.List;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventChargingState;
import info.nightscout.androidaps.events.EventLocationChange;
import info.nightscout.androidaps.events.EventNetworkChange;
import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginDescription;
import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
import info.nightscout.androidaps.plugins.general.automation.actions.ActionNotification;
import info.nightscout.androidaps.plugins.general.automation.actions.ActionProfileSwitchPercent;
import info.nightscout.androidaps.plugins.general.automation.actions.ActionStartTempTarget;
import info.nightscout.androidaps.plugins.general.automation.actions.ActionStopTempTarget;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.services.LocationService;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.T;
public class AutomationPlugin extends PluginBase {
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
private final String key_AUTOMATION_EVENTS = "AUTOMATION_EVENTS";
private static AutomationPlugin plugin = null;
public static AutomationPlugin getPlugin() {
if (plugin == null)
plugin = new AutomationPlugin();
return plugin;
}
private final List<AutomationEvent> automationEvents = new ArrayList<>();
private EventLocationChange eventLocationChange;
private EventChargingState eventChargingState;
private EventNetworkChange eventNetworkChange;
List<String> executionLog = new ArrayList<>();
private Handler loopHandler = new Handler();
private Runnable refreshLoop = new Runnable() {
@Override
public void run() {
processActions();
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs());
}
};
private AutomationPlugin() {
super(new PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(AutomationFragment.class.getName())
.pluginName(R.string.automation)
.shortName(R.string.automation_short)
.preferencesId(R.xml.pref_automation)
.description(R.string.automation_description)
);
}
@Override
protected void onStart() {
Context context = MainApp.instance().getApplicationContext();
context.startService(new Intent(context, LocationService.class));
MainApp.bus().register(this);
super.onStart();
loadFromSP();
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs());
}
@Override
protected void onStop() {
loopHandler.removeCallbacks(refreshLoop);
Context context = MainApp.instance().getApplicationContext();
context.stopService(new Intent(context, LocationService.class));
MainApp.bus().unregister(this);
}
public List<AutomationEvent> getAutomationEvents() {
return automationEvents;
}
public EventLocationChange getEventLocationChange() {
return eventLocationChange;
}
public EventChargingState getEventChargingState() {
return eventChargingState;
}
public EventNetworkChange getEventNetworkChange() {
return eventNetworkChange;
}
private void storeToSP() {
JSONArray array = new JSONArray();
try {
for (AutomationEvent event : getAutomationEvents()) {
array.put(new JSONObject(event.toJSON()));
}
} catch (JSONException e) {
e.printStackTrace();
}
SP.putString(key_AUTOMATION_EVENTS, array.toString());
}
private void loadFromSP() {
automationEvents.clear();
String data = SP.getString(key_AUTOMATION_EVENTS, "");
if (!data.equals("")) {
try {
JSONArray array = new JSONArray(data);
for (int i = 0; i < array.length(); i++) {
JSONObject o = array.getJSONObject(i);
AutomationEvent event = new AutomationEvent().fromJSON(o.toString());
automationEvents.add(event);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
@Subscribe
public void onEventPreferenceChange(EventPreferenceChange e) {
if (e.isChanged(R.string.key_location)) {
Context context = MainApp.instance().getApplicationContext();
context.stopService(new Intent(context, LocationService.class));
context.startService(new Intent(context, LocationService.class));
}
}
@Subscribe
public void onEvent(EventAutomationDataChanged e) {
storeToSP();
}
@Subscribe
public void onEventLocationChange(EventLocationChange e) {
eventLocationChange = e;
if (e != null)
log.debug(String.format("Grabbed location: %f %f Provider: %s", e.location.getLatitude(), e.location.getLongitude(), e.location.getProvider()));
processActions();
}
@Subscribe
public void onEventChargingState(EventChargingState e) {
eventChargingState = e;
processActions();
}
@Subscribe
public void onEventNetworkChange(EventNetworkChange e) {
eventNetworkChange = e;
processActions();
}
@Subscribe
public void onEventAutosensCalculationFinished(EventAutosensCalculationFinished e) {
processActions();
}
private synchronized void processActions() {
if (!isEnabled(PluginType.GENERAL))
return;
if (L.isEnabled(L.AUTOMATION))
log.debug("processActions");
for (AutomationEvent event : getAutomationEvents()) {
if (event.getTrigger().shouldRun() && event.getPreconditions().shouldRun()) {
List<Action> actions = event.getActions();
for (Action action : actions) {
action.doAction(new Callback() {
@Override
public void run() {
StringBuilder sb = new StringBuilder();
sb.append(DateUtil.timeString(DateUtil.now()));
sb.append(" ");
sb.append(result.success ? "" : "X");
sb.append(" ");
sb.append(event.getTitle());
sb.append(": ");
sb.append(action.shortDescription());
sb.append(": ");
sb.append(result.comment);
executionLog.add(sb.toString());
if (L.isEnabled(L.AUTOMATION))
log.debug("Executed: " + sb.toString());
MainApp.bus().post(new EventAutomationUpdateGui());
}
});
}
event.getTrigger().executed(DateUtil.now());
}
}
storeToSP(); // save last run time
}
public final List<Action> getActionDummyObjects() {
return new ArrayList<Action>() {{
//add(new ActionLoopDisable());
//add(new ActionLoopEnable());
//add(new ActionLoopResume());
//add(new ActionLoopSuspend());
add(new ActionStartTempTarget());
add(new ActionStopTempTarget());
add(new ActionNotification());
add(new ActionProfileSwitchPercent());
}};
}
}

View file

@ -0,0 +1,198 @@
package info.nightscout.androidaps.plugins.general.automation
import android.content.Intent
import android.os.Handler
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventChargingState
import info.nightscout.androidaps.events.EventLocationChange
import info.nightscout.androidaps.events.EventNetworkChange
import info.nightscout.androidaps.events.EventPreferenceChange
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.actions.*
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationDataChanged
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.services.LocationService
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.SP
import info.nightscout.androidaps.utils.T
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import org.slf4j.LoggerFactory
import java.util.*
object AutomationPlugin : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL)
.fragmentClass(AutomationFragment::class.qualifiedName)
.pluginName(R.string.automation)
.shortName(R.string.automation_short)
.preferencesId(R.xml.pref_automation)
.description(R.string.automation_description)) {
private val log = LoggerFactory.getLogger(L.AUTOMATION)
private var disposable: CompositeDisposable = CompositeDisposable()
private const val key_AUTOMATION_EVENTS = "AUTOMATION_EVENTS"
val automationEvents = ArrayList<AutomationEvent>()
var eventLocationChange: EventLocationChange? = null
private set
var executionLog: MutableList<String> = ArrayList()
private val loopHandler = Handler()
private lateinit var refreshLoop: Runnable
init {
refreshLoop = Runnable {
processActions()
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs())
}
}
operator fun CompositeDisposable.plusAssign(disposable: Disposable) {
add(disposable)
}
override fun onStart() {
val context = MainApp.instance().applicationContext
context.startService(Intent(context, LocationService::class.java))
MainApp.bus().register(this)
super.onStart()
loadFromSP()
loopHandler.postDelayed(refreshLoop, T.mins(1).msecs())
disposable += RxBus
.toObservable(EventPreferenceChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ e ->
if (e.isChanged(R.string.key_location)) {
val ctx = MainApp.instance().applicationContext
ctx.stopService(Intent(ctx, LocationService::class.java))
ctx.startService(Intent(ctx, LocationService::class.java))
}
}, {})
disposable += RxBus
.toObservable(EventAutomationDataChanged::class.java)
.observeOn(Schedulers.io())
.subscribe({ storeToSP() }, {})
disposable += RxBus
.toObservable(EventLocationChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ e ->
eventLocationChange = e
if (e != null)
log.debug("Grabbed location: $e.location.latitude $e.location.longitude Provider: $e.location.provider")
processActions()
}, {})
disposable += RxBus
.toObservable(EventChargingState::class.java)
.observeOn(Schedulers.io())
.subscribe({ processActions() }, {})
disposable += RxBus
.toObservable(EventNetworkChange::class.java)
.observeOn(Schedulers.io())
.subscribe({ processActions() }, {})
disposable += RxBus
.toObservable(EventAutosensCalculationFinished::class.java)
.observeOn(Schedulers.io())
.subscribe({ processActions() }, {})
}
override fun onStop() {
disposable.clear()
loopHandler.removeCallbacks(refreshLoop)
val context = MainApp.instance().applicationContext
context.stopService(Intent(context, LocationService::class.java))
}
private fun storeToSP() {
val array = JSONArray()
try {
for (event in automationEvents) {
array.put(JSONObject(event.toJSON()))
}
} catch (e: JSONException) {
e.printStackTrace()
}
SP.putString(key_AUTOMATION_EVENTS, array.toString())
}
private fun loadFromSP() {
automationEvents.clear()
val data = SP.getString(key_AUTOMATION_EVENTS, "")
if (data != "") {
try {
val array = JSONArray(data)
for (i in 0 until array.length()) {
val o = array.getJSONObject(i)
val event = AutomationEvent().fromJSON(o.toString())
automationEvents.add(event)
}
} catch (e: JSONException) {
e.printStackTrace()
}
}
}
@Synchronized
private fun processActions() {
if (!isEnabled(PluginType.GENERAL))
return
if (L.isEnabled(L.AUTOMATION))
log.debug("processActions")
for (event in automationEvents) {
if (event.trigger.shouldRun() && event.preconditions.shouldRun()) {
val actions = event.actions
for (action in actions) {
action.doAction(object : Callback() {
override fun run() {
val sb = StringBuilder()
sb.append(DateUtil.timeString(DateUtil.now()))
sb.append(" ")
sb.append(if (result.success) "" else "X")
sb.append(" ")
sb.append(event.title)
sb.append(": ")
sb.append(action.shortDescription())
sb.append(": ")
sb.append(result.comment)
executionLog.add(sb.toString())
if (L.isEnabled(L.AUTOMATION))
log.debug("Executed: $sb")
MainApp.bus().post(EventAutomationUpdateGui())
}
})
}
event.trigger.executed(DateUtil.now())
}
}
storeToSP() // save last run time
}
fun getActionDummyObjects(): List<Action> {
return listOf(
//ActionLoopDisable(),
//ActionLoopEnable(),
//ActionLoopResume(),
//ActionLoopSuspend(),
ActionStartTempTarget(),
ActionStopTempTarget(),
ActionNotification(),
ActionProfileSwitchPercent()
)
}
}

View file

@ -1,6 +1,7 @@
package info.nightscout.androidaps.plugins.general.automation;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -84,8 +85,14 @@ class EventListAdapter extends RecyclerView.Adapter<EventListAdapter.ViewHolder>
// edit event
holder.rootLayout.setOnClickListener(v -> {
EditEventDialog dialog = EditEventDialog.newInstance(event, false);
dialog.show(mFragmentManager, "EditEventDialog");
//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 (mFragmentManager != null)
dialog.show(mFragmentManager, "EditEventDialog");
});
}

View file

@ -1,5 +1,6 @@
package info.nightscout.androidaps.plugins.general.automation.dialogs;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -13,18 +14,18 @@ import androidx.recyclerview.widget.RecyclerView;
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.events.EventAutomationUpdateGui;
public class ActionListAdapter extends RecyclerView.Adapter<ActionListAdapter.ViewHolder> {
private final List<Action> mActionList;
private final FragmentManager mFragmentManager;
private final List<Action> actionList;
private final FragmentManager fragmentManager;
public ActionListAdapter(FragmentManager manager, List<Action> events) {
this.mActionList = events;
this.mFragmentManager = manager;
public ActionListAdapter(FragmentManager manager, List<Action> actions) {
this.actionList = actions;
this.fragmentManager = manager;
}
@NonNull
@ -36,24 +37,28 @@ public class ActionListAdapter extends RecyclerView.Adapter<ActionListAdapter.Vi
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
final Action action = mActionList.get(position);
final Action action = actionList.get(position);
holder.actionTitle.setText(action.shortDescription());
holder.layoutText.setOnClickListener(v -> {
if (action.hasDialog()) {
EditActionDialog dialog = EditActionDialog.newInstance(action);
dialog.show(mFragmentManager, "EditActionDialog");
Bundle args = new Bundle();
args.putInt("actionPosition", position);
args.putString("action", action.toJSON());
EditActionDialog dialog = new EditActionDialog();
dialog.setArguments(args);
dialog.show(fragmentManager, "EditActionDialog");
}
});
holder.iconTrash.setOnClickListener(v -> {
mActionList.remove(action);
actionList.remove(action);
notifyDataSetChanged();
MainApp.bus().post(new EventAutomationUpdateGui());
RxBus.INSTANCE.send(new EventAutomationUpdateGui());
});
}
@Override
public int getItemCount() {
return mActionList.size();
return actionList.size();
}
static class ViewHolder extends RecyclerView.ViewHolder {

View file

@ -16,6 +16,7 @@ import butterknife.OnClick;
import butterknife.Unbinder;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.bus.RxBus;
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;
@ -23,10 +24,6 @@ import info.nightscout.androidaps.plugins.general.automation.events.EventAutomat
public class ChooseActionDialog extends DialogFragment {
public interface OnClickListener {
void onClick(Action newActionObject);
}
private Unbinder mUnbinder;
@BindView(R.id.radioGroup)
@ -37,7 +34,7 @@ public class ChooseActionDialog extends DialogFragment {
View view = inflater.inflate(R.layout.automation_dialog_choose_action, container, false);
mUnbinder = ButterKnife.bind(this, view);
for (Action a : AutomationPlugin.getPlugin().getActionDummyObjects()) {
for (Action a : AutomationPlugin.INSTANCE.getActionDummyObjects()) {
RadioButton radioButton = new RadioButton(getContext());
radioButton.setText(a.friendlyName());
radioButton.setTag(a);
@ -96,8 +93,8 @@ public class ChooseActionDialog extends DialogFragment {
@OnClick(R.id.ok)
public void onButtonOk(View unused) {
dismiss();
MainApp.bus().post(new EventAutomationAddAction(instantiateAction()));
MainApp.bus().post(new EventAutomationUpdateGui());
RxBus.INSTANCE.send(new EventAutomationAddAction(instantiateAction()));
RxBus.INSTANCE.send(new EventAutomationUpdateGui());
}
@OnClick(R.id.cancel)

View file

@ -1,98 +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.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import org.json.JSONException;
import org.json.JSONObject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateGui;
public class EditActionDialog extends DialogFragment {
private static Action resultAction;
private Unbinder mUnbinder;
private Action mAction;
@BindView(R.id.layout_root)
LinearLayout mRootLayout;
@BindView(R.id.viewActionTitle)
TextView mViewActionTitle;
public static EditActionDialog newInstance(Action action) {
Bundle args = new Bundle();
EditActionDialog fragment = new EditActionDialog();
fragment.setArguments(args);
resultAction = action;
return fragment;
}
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.automation_dialog_action, container, false);
mUnbinder = ButterKnife.bind(this, view);
// get json data for action
String actionData = null;
if (savedInstanceState != null) {
actionData = savedInstanceState.getString("action");
}
if (actionData == null) {
actionData = resultAction.toJSON();
}
// create action from json
try {
mAction = Action.instantiate(new JSONObject(actionData));
} catch (JSONException e) {
e.printStackTrace();
}
if (mAction != null) {
mViewActionTitle.setText(mAction.friendlyName());
mRootLayout.removeAllViews();
mAction.generateDialog(mRootLayout);
}
return view;
}
@Override
public void onDestroyView() {
mUnbinder.unbind();
super.onDestroyView();
}
@OnClick(R.id.ok)
public void onButtonOk(View unused) {
resultAction.apply(mAction);
dismiss();
MainApp.bus().post(new EventAutomationUpdateGui());
}
@OnClick(R.id.cancel)
public void onButtonCancel(View unused) {
dismiss();
}
@Override
public void onSaveInstanceState(Bundle bundle) {
bundle.putString("action", mAction.toJSON());
}
}

View file

@ -0,0 +1,61 @@
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.Button
import androidx.fragment.app.DialogFragment
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.EventAutomationUpdateAction
import kotlinx.android.synthetic.main.automation_dialog_action.*
import org.json.JSONObject
class EditActionDialog : DialogFragment() {
private var action: Action? = null
private var actionPosition: Int = -1
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// load data from bundle
(savedInstanceState ?: arguments)?.let { bundle ->
actionPosition = bundle.getInt("actionPosition", -1)
bundle.getString("action")?.let { action = Action.instantiate(JSONObject(it)) }
}
dialog.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.automation_dialog_action, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
action?.let {
automation_actionTitle.setText(it.friendlyName())
automation_editActionLayout.removeAllViews()
it.generateDialog(automation_editActionLayout)
}
// OK button
view.findViewById<Button>(R.id.ok).setOnClickListener {
dismiss()
action?.let {
RxBus.send(EventAutomationUpdateAction(it, actionPosition))
}
}
// Cancel button
view.findViewById<Button>(R.id.cancel).setOnClickListener { dismiss() }
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
action?.let {
bundle.putInt("actionPosition", actionPosition)
bundle.putString("action", it.toJSON())
}
}
}

View file

@ -1,223 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.dialogs;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.textfield.TextInputEditText;
import com.squareup.otto.Subscribe;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent;
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
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.EventAutomationUpdateGui;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector;
public class EditEventDialog extends DialogFragment {
public interface OnClickListener {
void onClick(AutomationEvent event);
}
private static AutomationEvent staticEvent;
@BindView(R.id.inputEventTitle)
TextInputEditText mEditEventTitle;
@BindView(R.id.editTrigger)
TextView mEditTrigger;
@BindView(R.id.addAction)
TextView mAddAction;
@BindView(R.id.triggerDescription)
TextView mTriggerDescription;
@BindView(R.id.forcedtriggerdescription)
TextView mForcedTriggerDescription;
@BindView(R.id.forcedtriggerdescriptionlabel)
TextView mForcedTriggerDescriptionLabel;
@BindView(R.id.actionListView)
RecyclerView mActionListView;
private Unbinder mUnbinder;
private ActionListAdapter mActionListAdapter;
private AutomationEvent mEvent;
private boolean mAddNew;
public static EditEventDialog newInstance(AutomationEvent event, boolean addNew) {
staticEvent = event;
Bundle args = new Bundle();
EditEventDialog fragment = new EditEventDialog();
fragment.setArguments(args);
// clone event
try {
fragment.mEvent = new AutomationEvent().fromJSON(event.toJSON());
} catch (Exception e) {
e.printStackTrace();
}
fragment.mAddNew = addNew;
return fragment;
}
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.automation_dialog_event, container, false);
mUnbinder = ButterKnife.bind(this, view);
// load data from bundle
if (savedInstanceState != null) {
String eventData = savedInstanceState.getString("event");
if (eventData != null) mEvent = new AutomationEvent().fromJSON(eventData);
mAddNew = savedInstanceState.getBoolean("addNew");
} else if (mAddNew) {
mEvent.setTrigger(new TriggerConnector(TriggerConnector.Type.OR));
}
// event title
mEditEventTitle.setText(mEvent.getTitle());
// display root trigger
mTriggerDescription.setText(mEvent.getTrigger().friendlyDescription());
mEditTrigger.setOnClickListener(v -> {
EditTriggerDialog dialog = EditTriggerDialog.newInstance(mEvent.getTrigger());
if (getFragmentManager() != null)
dialog.show(getFragmentManager(), "EditTriggerDialog");
});
// setup action list view
mActionListAdapter = new ActionListAdapter(getFragmentManager(), mEvent.getActions());
mActionListView.setLayoutManager(new LinearLayoutManager(getContext()));
mActionListView.setAdapter(mActionListAdapter);
mAddAction.setOnClickListener(v -> {
FragmentManager fragmentManager = getFragmentManager();
if (fragmentManager != null)
new ChooseActionDialog().show(fragmentManager, "ChooseActionDialog");
});
showPreconditions();
MainApp.bus().register(this);
return view;
}
@Override
public void onDestroyView() {
MainApp.bus().unregister(this);
mUnbinder.unbind();
super.onDestroyView();
}
@Subscribe
public void onEventAutomationUpdateGui(EventAutomationUpdateGui ignored) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(() -> {
mActionListAdapter.notifyDataSetChanged();
showPreconditions();
});
}
@Subscribe
public void onEventAutomationAddAction(EventAutomationAddAction event) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(() -> {
mEvent.addAction(event.getAction());
mActionListAdapter.notifyDataSetChanged();
});
}
@Subscribe
public void onEventAutomationUpdateTrigger(EventAutomationUpdateTrigger event) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(() -> {
mEvent.setTrigger(event.getTrigger());
mTriggerDescription.setText(mEvent.getTrigger().friendlyDescription());
});
}
@OnClick(R.id.ok)
public void onButtonOk(View unused) {
// check for title
String title = mEditEventTitle.getText().toString();
if (title.isEmpty()) {
Toast.makeText(getContext(), R.string.automation_missing_task_name, Toast.LENGTH_LONG).show();
return;
}
mEvent.setTitle(title);
// check for at least one trigger
TriggerConnector con = (TriggerConnector) mEvent.getTrigger();
if (con.size() == 0) {
Toast.makeText(getContext(), R.string.automation_missing_trigger, Toast.LENGTH_LONG).show();
return;
}
// check for at least one action
if (mEvent.getActions().isEmpty()) {
Toast.makeText(getContext(), R.string.automation_missing_action, Toast.LENGTH_LONG).show();
return;
}
// apply changes
staticEvent.fromJSON(mEvent.toJSON());
// add new
if (mAddNew) {
final AutomationPlugin plugin = AutomationPlugin.getPlugin();
plugin.getAutomationEvents().add(mEvent);
}
dismiss();
MainApp.bus().post(new EventAutomationDataChanged());
}
@OnClick(R.id.cancel)
public void onButtonCancel(View unused) {
dismiss();
}
@Override
public void onSaveInstanceState(Bundle bundle) {
bundle.putString("event", mEvent.toJSON());
bundle.putBoolean("addNew", mAddNew);
}
private void showPreconditions() {
TriggerConnector forcedTriggers = mEvent.getPreconditions();
if (forcedTriggers.size() > 0) {
mForcedTriggerDescription.setVisibility(View.VISIBLE);
mForcedTriggerDescriptionLabel.setVisibility(View.VISIBLE);
mForcedTriggerDescription.setText(forcedTriggers.friendlyDescription());
} else {
mForcedTriggerDescription.setVisibility(View.GONE);
mForcedTriggerDescriptionLabel.setVisibility(View.GONE);
}
}
}

View file

@ -0,0 +1,154 @@
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.Button
import androidx.fragment.app.DialogFragment
import androidx.recyclerview.widget.LinearLayoutManager
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
import info.nightscout.androidaps.plugins.general.automation.events.*
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector
import info.nightscout.androidaps.utils.ToastUtils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.automation_dialog_event.*
class EditEventDialog : DialogFragment() {
private var actionListAdapter: ActionListAdapter? = null
private var event: AutomationEvent = AutomationEvent()
private var position: Int = -1
private var disposable: CompositeDisposable = CompositeDisposable()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// load data from bundle
(savedInstanceState ?: arguments)?.let { bundle ->
position = bundle.getInt("position", -1)
bundle.getString("event")?.let { event = AutomationEvent().fromJSON(it) }
}
dialog.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.automation_dialog_event, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
automation_inputEventTitle.setText(event.title)
automation_triggerDescription.text = event.trigger.friendlyDescription()
automation_editTrigger.setOnClickListener {
val args = Bundle()
args.putString("trigger", event.trigger.toJSON())
val dialog = EditTriggerDialog()
dialog.arguments = args
fragmentManager?.let { dialog.show(it, "EditTriggerDialog") }
}
// setup action list view
actionListAdapter = ActionListAdapter(fragmentManager, event.actions)
automation_actionListView.layoutManager = LinearLayoutManager(context)
automation_actionListView.adapter = actionListAdapter
automation_addAction.setOnClickListener { fragmentManager?.let { ChooseActionDialog().show(it, "ChooseActionDialog") } }
// OK button
view.findViewById<Button>(R.id.ok).setOnClickListener {
// check for title
val title = automation_inputEventTitle.text.toString()
if (title.isEmpty()) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_task_name)
return@setOnClickListener
}
event.title = title
// check for at least one trigger
val con = event.trigger as TriggerConnector
if (con.size() == 0) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_trigger)
return@setOnClickListener
}
// check for at least one action
if (event.actions.isEmpty()) {
ToastUtils.showToastInUiThread(context, R.string.automation_missing_action)
return@setOnClickListener
}
// store
if (position == -1)
AutomationPlugin.automationEvents.add(event)
else
AutomationPlugin.automationEvents[position] = event
dismiss()
RxBus.send(EventAutomationDataChanged())
}
// Cancel button
view.findViewById<Button>(R.id.cancel).setOnClickListener { dismiss() }
showPreconditions()
disposable.add(RxBus
.toObservable(EventAutomationUpdateGui::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
actionListAdapter?.notifyDataSetChanged()
showPreconditions()
}, {})
)
disposable.add(RxBus
.toObservable(EventAutomationAddAction::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
event.addAction(it.action)
actionListAdapter?.notifyDataSetChanged()
}, {})
)
disposable.add(RxBus
.toObservable(EventAutomationUpdateTrigger::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
event.trigger = it.trigger
automation_triggerDescription.text = event.trigger.friendlyDescription()
}, {})
)
disposable.add(RxBus
.toObservable(EventAutomationUpdateAction::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
event.actions[it.position] = it.action
actionListAdapter?.notifyDataSetChanged()
}, {})
)
}
override fun onDestroyView() {
super.onDestroyView()
disposable.clear()
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
bundle.putString("event", event.toJSON())
bundle.putInt("position", position)
}
private fun showPreconditions() {
val forcedTriggers = event.preconditions
if (forcedTriggers.size() > 0) {
automation_forcedTriggerDescription.visibility = View.VISIBLE
automation_forcedTriggerDescriptionLabel.visibility = View.VISIBLE
automation_forcedTriggerDescription.text = forcedTriggers.friendlyDescription()
} else {
automation_forcedTriggerDescription.visibility = View.GONE
automation_forcedTriggerDescriptionLabel.visibility = View.GONE
}
}
}

View file

@ -1,82 +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.LinearLayout;
import androidx.annotation.NonNull;
import androidx.fragment.app.DialogFragment;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.Unbinder;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger;
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
public class EditTriggerDialog extends DialogFragment {
public interface OnClickListener {
void onClick(Trigger newTriggerObject);
}
@BindView(R.id.layoutTrigger)
LinearLayout mLayoutTrigger;
private Trigger mTrigger;
private Unbinder mUnbinder;
public static EditTriggerDialog newInstance(Trigger trigger) {
Bundle args = new Bundle();
args.putString("trigger", trigger.toJSON());
EditTriggerDialog fragment = new EditTriggerDialog();
fragment.setArguments(args);
return fragment;
}
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false);
mUnbinder = ButterKnife.bind(this, view);
// load data from bundle
Bundle bundle = savedInstanceState != null ? savedInstanceState : getArguments();
if (bundle != null) {
String triggerData = bundle.getString("trigger");
if (triggerData != null) mTrigger = Trigger.instantiate(triggerData);
}
// display root trigger
if (mTrigger != null) {
mTrigger.generateDialog(mLayoutTrigger, getFragmentManager());
}
return view;
}
@Override
public void onDestroyView() {
mUnbinder.unbind();
super.onDestroyView();
}
@OnClick(R.id.ok)
public void onButtonOk(View unused) {
dismiss();
MainApp.bus().post(new EventAutomationUpdateTrigger(mTrigger));
}
@OnClick(R.id.cancel)
public void onButtonCancel(View unused) {
dismiss();
}
@Override
public void onSaveInstanceState(Bundle bundle) {
bundle.putString("trigger", mTrigger.toJSON());
}
}

View file

@ -0,0 +1,50 @@
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.Button
import androidx.fragment.app.DialogFragment
import info.nightscout.androidaps.R
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.automation.events.EventAutomationUpdateTrigger
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
import kotlinx.android.synthetic.main.automation_dialog_edit_trigger.*
class EditTriggerDialog : DialogFragment() {
private var trigger: Trigger? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// load data from bundle
(savedInstanceState ?: arguments)?.let { bundle ->
bundle.getString("trigger")?.let { trigger = Trigger.instantiate(it) }
}
dialog.setCanceledOnTouchOutside(false)
return inflater.inflate(R.layout.automation_dialog_edit_trigger, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// display root trigger
trigger?.let { it.generateDialog(automation_layoutTrigger, fragmentManager) }
// OK button
view.findViewById<Button>(R.id.ok).setOnClickListener {
dismiss()
RxBus.send(EventAutomationUpdateTrigger(trigger!!))
}
// Cancel button
view.findViewById<Button>(R.id.cancel).setOnClickListener { dismiss() }
}
override fun onSaveInstanceState(bundle: Bundle) {
super.onSaveInstanceState(bundle)
trigger?.let { bundle.putString("trigger", it.toJSON()) }
}
}

View file

@ -1,16 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.events;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
public class EventAutomationAddAction extends Event {
private Action action;
public EventAutomationAddAction(Action action) {
this.action = action;
}
public Action getAction() {
return action;
}
}

View file

@ -0,0 +1,6 @@
package info.nightscout.androidaps.plugins.general.automation.events
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.plugins.general.automation.actions.Action
class EventAutomationAddAction(val action: Action) : Event()

View file

@ -1,6 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.events;
import info.nightscout.androidaps.events.Event;
public class EventAutomationDataChanged extends Event {
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.plugins.general.automation.events
import info.nightscout.androidaps.events.Event
class EventAutomationDataChanged : Event()

View file

@ -0,0 +1,7 @@
package info.nightscout.androidaps.plugins.general.automation.events
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.plugins.general.automation.actions.Action
class EventAutomationUpdateAction(val action: Action, val position : Int) : Event() {
}

View file

@ -1,6 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.events;
import info.nightscout.androidaps.events.Event;
public class EventAutomationUpdateGui extends Event {
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.plugins.general.automation.events
import info.nightscout.androidaps.events.Event
class EventAutomationUpdateGui : Event()

View file

@ -1,16 +0,0 @@
package info.nightscout.androidaps.plugins.general.automation.events;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger;
public class EventAutomationUpdateTrigger extends Event {
private Trigger trigger;
public EventAutomationUpdateTrigger(Trigger trigger) {
this.trigger = trigger;
}
public Trigger getTrigger() {
return trigger;
}
}

View file

@ -0,0 +1,6 @@
package info.nightscout.androidaps.plugins.general.automation.events
import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.plugins.general.automation.triggers.Trigger
class EventAutomationUpdateTrigger(val trigger: Trigger) : Event()

View file

@ -38,7 +38,7 @@ public class TriggerLocation extends Trigger {
InputString name = new InputString();
Runnable buttonAction = () -> {
EventLocationChange event = AutomationPlugin.getPlugin().getEventLocationChange();
EventLocationChange event = AutomationPlugin.INSTANCE.getEventLocationChange();
if (event != null) {
latitude.setValue(event.location.getLatitude());
longitude.setValue(event.location.getLongitude());
@ -62,7 +62,7 @@ public class TriggerLocation extends Trigger {
@Override
public synchronized boolean shouldRun() {
EventLocationChange eventLocationChange = AutomationPlugin.getPlugin().getEventLocationChange();
EventLocationChange eventLocationChange = AutomationPlugin.INSTANCE.getEventLocationChange();
if (eventLocationChange == null)
return false;
@ -164,7 +164,7 @@ public class TriggerLocation extends Trigger {
.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 InputButton(MainApp.gs(R.string.currentlocation), buttonAction), AutomationPlugin.getPlugin().getEventLocationChange() != null)
.add(new InputButton(MainApp.gs(R.string.currentlocation), buttonAction), AutomationPlugin.INSTANCE.getEventLocationChange() != null)
.build(root);
}
}

View file

@ -15,12 +15,12 @@ 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.AutomationPlugin;
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;
@ -52,7 +52,7 @@ public class TriggerWifiSsid extends Trigger {
@Override
public synchronized boolean shouldRun() {
EventNetworkChange eventNetworkChange = AutomationPlugin.getPlugin().getEventNetworkChange();
EventNetworkChange eventNetworkChange = NetworkChangeReceiver.getLastEvent();
if (eventNetworkChange == null)
return false;

View file

@ -38,4 +38,8 @@ public class ChargingStateReceiver extends BroadcastReceiver {
static public boolean isCharging() {
return lastEvent != null && lastEvent.isCharging;
}
static public EventChargingState getLastEvent() {
return lastEvent;
}
}

View file

@ -70,4 +70,8 @@ public class NetworkChangeReceiver extends BroadcastReceiver {
public static boolean isWifiConnected() {
return lastEvent != null && lastEvent.wifiConnected;
}
public static EventNetworkChange getLastEvent() {
return lastEvent;
}
}

View file

@ -6,12 +6,19 @@ import android.os.Handler;
import android.os.Looper;
import android.widget.Toast;
import androidx.annotation.IdRes;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
public class ToastUtils {
public static void showToastInUiThread(final Context ctx,
final int stringId) {
showToastInUiThread(ctx, MainApp.gs(stringId));
}
public static void showToastInUiThread(final Context ctx,
final String string) {

View file

@ -11,7 +11,7 @@
android:orientation="vertical">
<TextView
android:id="@+id/viewActionTitle"
android:id="@+id/automation_actionTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
@ -19,7 +19,7 @@
android:textAppearance="?android:attr/textAppearanceLarge" />
<LinearLayout
android:id="@+id/layout_root"
android:id="@+id/automation_editActionLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusableInTouchMode="true"

View file

@ -13,7 +13,7 @@
android:padding="10dp">
<android.support.design.widget.TextInputEditText
android:id="@+id/inputEventTitle"
android:id="@+id/automation_inputEventTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/eventname" />
@ -35,7 +35,7 @@
android:text="@string/if_label"/>
<TextView
android:id="@+id/editTrigger"
android:id="@+id/automation_editTrigger"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
@ -45,7 +45,7 @@
</RelativeLayout>
<TextView
android:id="@+id/triggerDescription"
android:id="@+id/automation_triggerDescription"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"

View file

@ -18,7 +18,7 @@
android:text="@string/triggers" />
<LinearLayout
android:id="@+id/layoutTrigger"
android:id="@+id/automation_layoutTrigger"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"

View file

@ -13,7 +13,7 @@
android:padding="10dp">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/inputEventTitle"
android:id="@+id/automation_inputEventTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/taskname" />
@ -36,7 +36,7 @@
android:textStyle="bold" />
<TextView
android:id="@+id/editTrigger"
android:id="@+id/automation_editTrigger"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
@ -48,7 +48,7 @@
</RelativeLayout>
<TextView
android:id="@+id/triggerDescription"
android:id="@+id/automation_triggerDescription"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"
@ -56,14 +56,14 @@
android:orientation="vertical" />
<TextView
android:id="@+id/forcedtriggerdescriptionlabel"
android:id="@+id/automation_forcedTriggerDescriptionLabel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/preconditions"
android:textStyle="bold" />
<TextView
android:id="@+id/forcedtriggerdescription"
android:id="@+id/automation_forcedTriggerDescription"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
@ -88,7 +88,7 @@
android:textStyle="bold" />
<TextView
android:id="@+id/addAction"
android:id="@+id/automation_addAction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
@ -100,7 +100,7 @@
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/actionListView"
android:id="@+id/automation_actionListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="10dp"

View file

@ -6,22 +6,22 @@
tools:context="info.nightscout.androidaps.plugins.general.automation.AutomationFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/eventListView"
android:id="@+id/automation_eventListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/logView"
android:layout_above="@+id/automation_logView"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginBottom="-100dp" />
<TextView
android:id="@+id/logView"
android:id="@+id/automation_logView"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentBottom="true" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fabAddEvent"
android:id="@+id/automation_fabAddEvent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"

View file

@ -17,23 +17,22 @@ import info.AAPSMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventNetworkChange;
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
import info.nightscout.androidaps.receivers.NetworkChangeReceiver;
import info.nightscout.androidaps.utils.DateUtil;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, Bus.class, AutomationPlugin.class, DateUtil.class})
@PrepareForTest({MainApp.class, Bus.class, NetworkChangeReceiver.class, DateUtil.class})
public class TriggerWifiSsidTest {
AutomationPlugin automationPlugin;
long now = 1514766900000L;
@Test
public void shouldRunTest() {
EventNetworkChange e = new EventNetworkChange();
when(automationPlugin.getEventNetworkChange()).thenReturn(e);
when(NetworkChangeReceiver.getLastEvent()).thenReturn(e);
TriggerWifiSsid t = new TriggerWifiSsid().setValue("aSSID").comparator(Comparator.Compare.IS_EQUAL);
@ -56,7 +55,7 @@ public class TriggerWifiSsidTest {
Assert.assertTrue(t.shouldRun());
// no network data
when(automationPlugin.getEventNetworkChange()).thenReturn(null);
when(NetworkChangeReceiver.getLastEvent()).thenReturn(null);
Assert.assertFalse(t.shouldRun());
}
@ -68,7 +67,7 @@ public class TriggerWifiSsidTest {
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.getComparator().getValue());
}
String json = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"lastRun\":0,\"ssid\":\"aSSID\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerWifiSsid\"}";
String json = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"lastRun\":0,\"ssid\":\"aSSID\"},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerWifiSsid\"}";
@Test
public void toJSONTest() {
@ -105,9 +104,7 @@ public class TriggerWifiSsidTest {
AAPSMocker.mockMainApp();
AAPSMocker.mockBus();
PowerMockito.mockStatic(AutomationPlugin.class);
automationPlugin = PowerMockito.mock(AutomationPlugin.class);
when(AutomationPlugin.getPlugin()).thenReturn(automationPlugin);
PowerMockito.mockStatic(NetworkChangeReceiver.class);
PowerMockito.mockStatic(DateUtil.class);
when(DateUtil.now()).thenReturn(now);