Automation: split recurring and nonrecurring time
This commit is contained in:
parent
dc0846eab9
commit
1f62c820ca
6 changed files with 452 additions and 228 deletions
|
@ -19,6 +19,7 @@ import butterknife.Unbinder;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
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.TriggerBg;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBg;
|
||||||
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerRecurringTime;
|
||||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime;
|
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime;
|
||||||
|
|
||||||
public class ChooseTriggerDialog extends DialogFragment {
|
public class ChooseTriggerDialog extends DialogFragment {
|
||||||
|
@ -28,8 +29,9 @@ public class ChooseTriggerDialog extends DialogFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final List<Trigger> triggerDummyObjects = new ArrayList<Trigger>() {{
|
private static final List<Trigger> triggerDummyObjects = new ArrayList<Trigger>() {{
|
||||||
add(new TriggerBg());
|
add(new TriggerBg());
|
||||||
add(new TriggerTime());
|
add(new TriggerTime());
|
||||||
|
add(new TriggerRecurringTime());
|
||||||
}};
|
}};
|
||||||
|
|
||||||
private Unbinder mUnbinder;
|
private Unbinder mUnbinder;
|
||||||
|
@ -52,7 +54,7 @@ public class ChooseTriggerDialog extends DialogFragment {
|
||||||
View view = inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false);
|
View view = inflater.inflate(R.layout.automation_dialog_choose_trigger, container, false);
|
||||||
mUnbinder = ButterKnife.bind(this, view);
|
mUnbinder = ButterKnife.bind(this, view);
|
||||||
|
|
||||||
for(Trigger t : triggerDummyObjects) {
|
for (Trigger t : triggerDummyObjects) {
|
||||||
RadioButton radioButton = new RadioButton(getContext());
|
RadioButton radioButton = new RadioButton(getContext());
|
||||||
radioButton.setText(t.friendlyName());
|
radioButton.setText(t.friendlyName());
|
||||||
radioButton.setTag(t);
|
radioButton.setTag(t);
|
||||||
|
@ -65,14 +67,14 @@ public class ChooseTriggerDialog extends DialogFragment {
|
||||||
checkedIndex = savedInstanceState.getInt("checkedIndex");
|
checkedIndex = savedInstanceState.getInt("checkedIndex");
|
||||||
}
|
}
|
||||||
|
|
||||||
((RadioButton)mRadioGroup.getChildAt(checkedIndex)).setChecked(true);
|
((RadioButton) mRadioGroup.getChildAt(checkedIndex)).setChecked(true);
|
||||||
|
|
||||||
return view;
|
return view;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getCheckedIndex() {
|
private int getCheckedIndex() {
|
||||||
for(int i = 0; i < mRadioGroup.getChildCount(); ++i) {
|
for (int i = 0; i < mRadioGroup.getChildCount(); ++i) {
|
||||||
if (((RadioButton)mRadioGroup.getChildAt(i)).isChecked())
|
if (((RadioButton) mRadioGroup.getChildAt(i)).isChecked())
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -0,0 +1,301 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.support.annotation.StringRes;
|
||||||
|
import android.support.v4.app.FragmentManager;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import com.dpro.widgets.WeekdaysPicker;
|
||||||
|
import com.google.common.base.Optional;
|
||||||
|
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.R;
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
import info.nightscout.androidaps.utils.JsonHelper;
|
||||||
|
import info.nightscout.androidaps.utils.T;
|
||||||
|
|
||||||
|
public class TriggerRecurringTime extends Trigger {
|
||||||
|
|
||||||
|
public enum DayOfWeek {
|
||||||
|
MONDAY,
|
||||||
|
TUESDAY,
|
||||||
|
WEDNESDAY,
|
||||||
|
THURSDAY,
|
||||||
|
FRIDAY,
|
||||||
|
SATURDAY,
|
||||||
|
SUNDAY;
|
||||||
|
|
||||||
|
private static final int[] calendarInts = new int[]{
|
||||||
|
Calendar.MONDAY,
|
||||||
|
Calendar.TUESDAY,
|
||||||
|
Calendar.WEDNESDAY,
|
||||||
|
Calendar.THURSDAY,
|
||||||
|
Calendar.FRIDAY,
|
||||||
|
Calendar.SATURDAY,
|
||||||
|
Calendar.SUNDAY
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[] fullNames = new int[]{
|
||||||
|
R.string.weekday_monday,
|
||||||
|
R.string.weekday_tuesday,
|
||||||
|
R.string.weekday_wednesday,
|
||||||
|
R.string.weekday_thursday,
|
||||||
|
R.string.weekday_friday,
|
||||||
|
R.string.weekday_saturday,
|
||||||
|
R.string.weekday_sunday
|
||||||
|
};
|
||||||
|
|
||||||
|
private static final int[] shortNames = new int[]{
|
||||||
|
R.string.weekday_monday_short,
|
||||||
|
R.string.weekday_tuesday_short,
|
||||||
|
R.string.weekday_wednesday_short,
|
||||||
|
R.string.weekday_thursday_short,
|
||||||
|
R.string.weekday_friday_short,
|
||||||
|
R.string.weekday_saturday_short,
|
||||||
|
R.string.weekday_sunday_short
|
||||||
|
};
|
||||||
|
|
||||||
|
public int toCalendarInt() {
|
||||||
|
return calendarInts[ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DayOfWeek fromCalendarInt(int day) {
|
||||||
|
for (int i = 0; i < calendarInts.length; ++i) {
|
||||||
|
if (calendarInts[i] == day)
|
||||||
|
return values()[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public @StringRes
|
||||||
|
int getFullName() {
|
||||||
|
return fullNames[ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public @StringRes
|
||||||
|
int getShortName() {
|
||||||
|
return shortNames[ordinal()];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final boolean[] weekdays = new boolean[DayOfWeek.values().length];
|
||||||
|
|
||||||
|
private long lastRun;
|
||||||
|
|
||||||
|
// Recurring
|
||||||
|
private int hour;
|
||||||
|
private int minute;
|
||||||
|
|
||||||
|
private long validTo;
|
||||||
|
|
||||||
|
public TriggerRecurringTime() {
|
||||||
|
super();
|
||||||
|
setAll(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private TriggerRecurringTime(TriggerRecurringTime triggerTime) {
|
||||||
|
super();
|
||||||
|
lastRun = triggerTime.lastRun;
|
||||||
|
hour = triggerTime.hour;
|
||||||
|
minute = triggerTime.minute;
|
||||||
|
validTo = triggerTime.validTo;
|
||||||
|
|
||||||
|
for (int i = 0; i < weekdays.length; ++i) {
|
||||||
|
weekdays[i] = triggerTime.weekdays[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAll(boolean value) {
|
||||||
|
for (DayOfWeek day : DayOfWeek.values()) {
|
||||||
|
set(day, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public TriggerRecurringTime set(DayOfWeek day, boolean value) {
|
||||||
|
weekdays[day.ordinal()] = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSet(DayOfWeek day) {
|
||||||
|
return weekdays[day.ordinal()];
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getLastRun() {
|
||||||
|
return lastRun;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldRun() {
|
||||||
|
if (validTo != 0 && DateUtil.now() > validTo)
|
||||||
|
return false;
|
||||||
|
Calendar c = Calendar.getInstance();
|
||||||
|
int scheduledDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
|
||||||
|
|
||||||
|
Calendar scheduledCal = DateUtil.gregorianCalendar();
|
||||||
|
scheduledCal.set(Calendar.HOUR_OF_DAY, hour);
|
||||||
|
scheduledCal.set(Calendar.MINUTE, minute);
|
||||||
|
scheduledCal.set(Calendar.SECOND, 0);
|
||||||
|
long scheduled = scheduledCal.getTimeInMillis();
|
||||||
|
|
||||||
|
if (isSet(DayOfWeek.fromCalendarInt(scheduledDayOfWeek))) {
|
||||||
|
if (DateUtil.now() >= scheduled && DateUtil.now() - scheduled < T.mins(5).msecs()) {
|
||||||
|
if (lastRun < scheduled)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toJSON() {
|
||||||
|
JSONObject object = new JSONObject();
|
||||||
|
JSONObject data = new JSONObject();
|
||||||
|
try {
|
||||||
|
data.put("lastRun", lastRun);
|
||||||
|
for (int i = 0; i < weekdays.length; ++i) {
|
||||||
|
data.put(DayOfWeek.values()[i].name(), weekdays[i]);
|
||||||
|
}
|
||||||
|
data.put("hour", hour);
|
||||||
|
data.put("minute", minute);
|
||||||
|
data.put("validTo", validTo);
|
||||||
|
object.put("type", TriggerRecurringTime.class.getName());
|
||||||
|
object.put("data", data);
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return object.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Trigger fromJSON(String data) {
|
||||||
|
JSONObject o;
|
||||||
|
try {
|
||||||
|
o = new JSONObject(data);
|
||||||
|
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
||||||
|
for (int i = 0; i < weekdays.length; ++i) {
|
||||||
|
weekdays[i] = JsonHelper.safeGetBoolean(o, DayOfWeek.values()[i].name());
|
||||||
|
}
|
||||||
|
hour = JsonHelper.safeGetInt(o, "hour");
|
||||||
|
minute = JsonHelper.safeGetInt(o, "minute");
|
||||||
|
validTo = JsonHelper.safeGetLong(o, "validTo");
|
||||||
|
} catch (JSONException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int friendlyName() {
|
||||||
|
return R.string.recurringTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String friendlyDescription() {
|
||||||
|
// TODO
|
||||||
|
return "Every ";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Optional<Integer> icon() {
|
||||||
|
return Optional.of(R.drawable.ic_access_alarm_24dp);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void notifyAboutRun(long time) {
|
||||||
|
lastRun = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Trigger duplicate() {
|
||||||
|
return new TriggerRecurringTime(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
TriggerRecurringTime lastRun(long lastRun) {
|
||||||
|
this.lastRun = lastRun;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TriggerRecurringTime validTo(long validTo) {
|
||||||
|
this.validTo = validTo;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TriggerRecurringTime hour(int hour) {
|
||||||
|
this.hour = hour;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
TriggerRecurringTime minute(int minute) {
|
||||||
|
this.minute = minute;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<Integer> getSelectedDays() {
|
||||||
|
List<Integer> selectedDays = new ArrayList<>();
|
||||||
|
for (int i = 0; i < weekdays.length; ++i) {
|
||||||
|
DayOfWeek day = DayOfWeek.values()[i];
|
||||||
|
boolean selected = weekdays[i];
|
||||||
|
if (selected) selectedDays.add(day.toCalendarInt());
|
||||||
|
}
|
||||||
|
return selectedDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public View createView(final Context context, FragmentManager fragmentManager) {
|
||||||
|
LinearLayout root = (LinearLayout) super.createView(context, fragmentManager);
|
||||||
|
|
||||||
|
// TODO: Replace external tool WeekdaysPicker with a self-made GUI element
|
||||||
|
WeekdaysPicker weekdaysPicker = new WeekdaysPicker(context);
|
||||||
|
weekdaysPicker.setEditable(true);
|
||||||
|
weekdaysPicker.setSelectedDays(getSelectedDays());
|
||||||
|
weekdaysPicker.setOnWeekdaysChangeListener((view, i, list) -> set(DayOfWeek.fromCalendarInt(i), list.contains(i)));
|
||||||
|
weekdaysPicker.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
|
||||||
|
root.addView(weekdaysPicker);
|
||||||
|
|
||||||
|
TextView dateButton = new TextView(context);
|
||||||
|
TextView timeButton = new TextView(context);
|
||||||
|
|
||||||
|
Date runAt = new Date();
|
||||||
|
runAt.setHours(hour);
|
||||||
|
runAt.setMinutes(minute);
|
||||||
|
timeButton.setText(DateUtil.timeString(runAt));
|
||||||
|
timeButton.setOnClickListener(view -> {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTime(runAt);
|
||||||
|
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||||
|
(view12, hourOfDay, minute, second) -> {
|
||||||
|
this.hour = hourOfDay;
|
||||||
|
this.minute = minute;
|
||||||
|
runAt.setHours(this.hour);
|
||||||
|
runAt.setMinutes(this.minute);
|
||||||
|
timeButton.setText(DateUtil.timeString(runAt));
|
||||||
|
},
|
||||||
|
calendar.get(Calendar.HOUR_OF_DAY),
|
||||||
|
calendar.get(Calendar.MINUTE),
|
||||||
|
DateFormat.is24HourFormat(context)
|
||||||
|
);
|
||||||
|
tpd.setThemeDark(true);
|
||||||
|
tpd.dismissOnPause(true);
|
||||||
|
android.app.FragmentManager fm = ((Activity) context).getFragmentManager();
|
||||||
|
tpd.show(fm, "Timepickerdialog");
|
||||||
|
});
|
||||||
|
|
||||||
|
root.addView(dateButton);
|
||||||
|
root.addView(timeButton);
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,22 @@
|
||||||
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||||
|
|
||||||
import android.support.v4.app.FragmentManager;
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.support.annotation.StringRes;
|
import android.support.v4.app.FragmentManager;
|
||||||
|
import android.text.format.DateFormat;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.dpro.widgets.WeekdaysPicker;
|
|
||||||
import com.google.common.base.Optional;
|
import com.google.common.base.Optional;
|
||||||
|
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
|
||||||
|
import com.wdullaer.materialdatetimepicker.time.TimePickerDialog;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.Date;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
|
@ -25,153 +26,24 @@ import info.nightscout.androidaps.utils.T;
|
||||||
|
|
||||||
public class TriggerTime extends Trigger {
|
public class TriggerTime extends Trigger {
|
||||||
|
|
||||||
public enum DayOfWeek {
|
private long runAt;
|
||||||
MONDAY,
|
|
||||||
TUESDAY,
|
|
||||||
WEDNESDAY,
|
|
||||||
THURSDAY,
|
|
||||||
FRIDAY,
|
|
||||||
SATURDAY,
|
|
||||||
SUNDAY;
|
|
||||||
|
|
||||||
private static final int[] calendarInts = new int[] {
|
|
||||||
Calendar.MONDAY,
|
|
||||||
Calendar.TUESDAY,
|
|
||||||
Calendar.WEDNESDAY,
|
|
||||||
Calendar.THURSDAY,
|
|
||||||
Calendar.FRIDAY,
|
|
||||||
Calendar.SATURDAY,
|
|
||||||
Calendar.SUNDAY
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final int[] fullNames = new int[] {
|
|
||||||
R.string.weekday_monday,
|
|
||||||
R.string.weekday_tuesday,
|
|
||||||
R.string.weekday_wednesday,
|
|
||||||
R.string.weekday_thursday,
|
|
||||||
R.string.weekday_friday,
|
|
||||||
R.string.weekday_saturday,
|
|
||||||
R.string.weekday_sunday
|
|
||||||
};
|
|
||||||
|
|
||||||
private static final int[] shortNames = new int[] {
|
|
||||||
R.string.weekday_monday_short,
|
|
||||||
R.string.weekday_tuesday_short,
|
|
||||||
R.string.weekday_wednesday_short,
|
|
||||||
R.string.weekday_thursday_short,
|
|
||||||
R.string.weekday_friday_short,
|
|
||||||
R.string.weekday_saturday_short,
|
|
||||||
R.string.weekday_sunday_short
|
|
||||||
};
|
|
||||||
|
|
||||||
public int toCalendarInt() {
|
|
||||||
return calendarInts[ordinal()];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DayOfWeek fromCalendarInt(int day) {
|
|
||||||
for(int i = 0; i < calendarInts.length; ++i) {
|
|
||||||
if (calendarInts[i] == day)
|
|
||||||
return values()[i];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public @StringRes int getFullName() {
|
|
||||||
return fullNames[ordinal()];
|
|
||||||
}
|
|
||||||
|
|
||||||
public @StringRes int getShortName() {
|
|
||||||
return shortNames[ordinal()];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final boolean[] weekdays = new boolean[DayOfWeek.values().length];
|
|
||||||
|
|
||||||
private long lastRun;
|
private long lastRun;
|
||||||
|
|
||||||
// Single execution
|
|
||||||
private long runAt;
|
|
||||||
|
|
||||||
// Recurring
|
|
||||||
private boolean recurring;
|
|
||||||
private int hour;
|
|
||||||
private int minute;
|
|
||||||
|
|
||||||
private long validTo;
|
|
||||||
|
|
||||||
public TriggerTime() {
|
public TriggerTime() {
|
||||||
super();
|
|
||||||
setAll(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private TriggerTime(TriggerTime triggerTime) {
|
private TriggerTime(TriggerTime triggerTime) {
|
||||||
super();
|
super();
|
||||||
lastRun = triggerTime.lastRun;
|
lastRun = triggerTime.lastRun;
|
||||||
runAt = triggerTime.runAt;
|
runAt = triggerTime.runAt;
|
||||||
recurring = triggerTime.recurring;
|
|
||||||
hour = triggerTime.hour;
|
|
||||||
minute = triggerTime.minute;
|
|
||||||
validTo = triggerTime.validTo;
|
|
||||||
|
|
||||||
for(int i = 0; i < weekdays.length; ++i) {
|
|
||||||
weekdays[i] = triggerTime.weekdays[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAll(boolean value) {
|
|
||||||
for(DayOfWeek day : DayOfWeek.values()) {
|
|
||||||
set(day, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public TriggerTime set(DayOfWeek day, boolean value) {
|
|
||||||
weekdays[day.ordinal()] = value;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSet(DayOfWeek day) {
|
|
||||||
return weekdays[day.ordinal()];
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLastRun() {
|
|
||||||
return lastRun;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getRunAt() {
|
|
||||||
return runAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRecurring() {
|
|
||||||
return recurring;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldRun() {
|
public boolean shouldRun() {
|
||||||
if (recurring) {
|
long now = DateUtil.now();
|
||||||
if (validTo != 0 && DateUtil.now() > validTo)
|
if (now >= runAt && now - runAt < T.mins(5).msecs())
|
||||||
return false;
|
return true;
|
||||||
Calendar c = Calendar.getInstance();
|
return false;
|
||||||
int scheduledDayOfWeek = c.get(Calendar.DAY_OF_WEEK);
|
|
||||||
|
|
||||||
Calendar scheduledCal = DateUtil.gregorianCalendar();
|
|
||||||
scheduledCal.set(Calendar.HOUR_OF_DAY, hour);
|
|
||||||
scheduledCal.set(Calendar.MINUTE, minute);
|
|
||||||
scheduledCal.set(Calendar.SECOND, 0);
|
|
||||||
long scheduled = scheduledCal.getTimeInMillis();
|
|
||||||
|
|
||||||
if (isSet(DayOfWeek.fromCalendarInt(scheduledDayOfWeek))) {
|
|
||||||
if (DateUtil.now() >= scheduled && DateUtil.now() - scheduled < T.mins(5).msecs()) {
|
|
||||||
if (lastRun < scheduled)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
long now = DateUtil.now();
|
|
||||||
if (now >= runAt && now - runAt < T.mins(5).msecs())
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -179,15 +51,8 @@ public class TriggerTime extends Trigger {
|
||||||
JSONObject object = new JSONObject();
|
JSONObject object = new JSONObject();
|
||||||
JSONObject data = new JSONObject();
|
JSONObject data = new JSONObject();
|
||||||
try {
|
try {
|
||||||
data.put("lastRun", lastRun);
|
|
||||||
data.put("runAt", runAt);
|
data.put("runAt", runAt);
|
||||||
data.put("recurring", recurring);
|
data.put("lastRun", lastRun);
|
||||||
for(int i = 0; i < weekdays.length; ++i) {
|
|
||||||
data.put(DayOfWeek.values()[i].name(), weekdays[i]);
|
|
||||||
}
|
|
||||||
data.put("hour", hour);
|
|
||||||
data.put("minute", minute);
|
|
||||||
data.put("validTo", validTo);
|
|
||||||
object.put("type", TriggerTime.class.getName());
|
object.put("type", TriggerTime.class.getName());
|
||||||
object.put("data", data);
|
object.put("data", data);
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
|
@ -203,13 +68,6 @@ public class TriggerTime extends Trigger {
|
||||||
o = new JSONObject(data);
|
o = new JSONObject(data);
|
||||||
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
lastRun = JsonHelper.safeGetLong(o, "lastRun");
|
||||||
runAt = JsonHelper.safeGetLong(o, "runAt");
|
runAt = JsonHelper.safeGetLong(o, "runAt");
|
||||||
recurring = JsonHelper.safeGetBoolean(o, "recurring");
|
|
||||||
for(int i = 0; i < weekdays.length; ++i) {
|
|
||||||
weekdays[i] = JsonHelper.safeGetBoolean(o, DayOfWeek.values()[i].name());
|
|
||||||
}
|
|
||||||
hour = JsonHelper.safeGetInt(o, "hour");
|
|
||||||
minute = JsonHelper.safeGetInt(o, "minute");
|
|
||||||
validTo = JsonHelper.safeGetLong(o, "validTo");
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -223,12 +81,7 @@ public class TriggerTime extends Trigger {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String friendlyDescription() {
|
public String friendlyDescription() {
|
||||||
if (recurring) {
|
return MainApp.gs(R.string.atspecifiedtime, DateUtil.dateAndTimeString(runAt));
|
||||||
// TODO
|
|
||||||
return "Every ";
|
|
||||||
} else {
|
|
||||||
return MainApp.gs(R.string.atspecifiedtime, DateUtil.dateAndTimeString(runAt));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -241,63 +94,74 @@ public class TriggerTime extends Trigger {
|
||||||
lastRun = time;
|
lastRun = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Trigger duplicate() {
|
|
||||||
return new TriggerTime(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerTime lastRun(long lastRun) {
|
|
||||||
this.lastRun = lastRun;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerTime runAt(long runAt) {
|
TriggerTime runAt(long runAt) {
|
||||||
this.runAt = runAt;
|
this.runAt = runAt;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerTime recurring(boolean recurring) {
|
@Override
|
||||||
this.recurring = recurring;
|
public Trigger duplicate() {
|
||||||
return this;
|
return new TriggerTime(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerTime validTo(long validTo) {
|
public long getRunAt() {
|
||||||
this.validTo = validTo;
|
return runAt;
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerTime hour(int hour) {
|
|
||||||
this.hour = hour;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerTime minute(int minute) {
|
|
||||||
this.minute = minute;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<Integer> getSelectedDays() {
|
|
||||||
List<Integer> selectedDays = new ArrayList<>();
|
|
||||||
for(int i = 0; i < weekdays.length; ++i) {
|
|
||||||
DayOfWeek day = DayOfWeek.values()[i];
|
|
||||||
boolean selected = weekdays[i];
|
|
||||||
if (selected) selectedDays.add(day.toCalendarInt());
|
|
||||||
}
|
|
||||||
return selectedDays;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View createView(Context context, FragmentManager fragmentManager) {
|
public View createView(final Context context, FragmentManager fragmentManager) {
|
||||||
LinearLayout root = (LinearLayout) super.createView(context, fragmentManager);
|
LinearLayout root = (LinearLayout) super.createView(context, fragmentManager);
|
||||||
|
//root.setOrientation(LinearLayout.HORIZONTAL);
|
||||||
|
|
||||||
// TODO: Replace external tool WeekdaysPicker with a self-made GUI element
|
TextView dateButton = new TextView(context);
|
||||||
WeekdaysPicker weekdaysPicker = new WeekdaysPicker(context);
|
TextView timeButton = new TextView(context);
|
||||||
weekdaysPicker.setEditable(true);
|
|
||||||
weekdaysPicker.setSelectedDays(getSelectedDays());
|
|
||||||
weekdaysPicker.setOnWeekdaysChangeListener((view, i, list) -> set(DayOfWeek.fromCalendarInt(i), list.contains(i)));
|
|
||||||
weekdaysPicker.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
|
||||||
|
|
||||||
root.addView(weekdaysPicker);
|
dateButton.setText(DateUtil.dateString(runAt));
|
||||||
|
timeButton.setText(DateUtil.timeString(runAt));
|
||||||
|
dateButton.setOnClickListener(view -> {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(runAt);
|
||||||
|
DatePickerDialog dpd = DatePickerDialog.newInstance(
|
||||||
|
(view1, year, monthOfYear, dayOfMonth) -> {
|
||||||
|
Date eventTime = new Date(runAt);
|
||||||
|
eventTime.setYear(year - 1900);
|
||||||
|
eventTime.setMonth(monthOfYear);
|
||||||
|
eventTime.setDate(dayOfMonth);
|
||||||
|
runAt = eventTime.getTime();
|
||||||
|
dateButton.setText(DateUtil.dateString(runAt));
|
||||||
|
},
|
||||||
|
calendar.get(Calendar.YEAR),
|
||||||
|
calendar.get(Calendar.MONTH),
|
||||||
|
calendar.get(Calendar.DAY_OF_MONTH)
|
||||||
|
);
|
||||||
|
dpd.setThemeDark(true);
|
||||||
|
dpd.dismissOnPause(true);
|
||||||
|
android.app.FragmentManager fm = ((Activity) context).getFragmentManager();
|
||||||
|
dpd.show(fm, "Datepickerdialog");
|
||||||
|
});
|
||||||
|
timeButton.setOnClickListener(view -> {
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setTimeInMillis(runAt);
|
||||||
|
TimePickerDialog tpd = TimePickerDialog.newInstance(
|
||||||
|
(view12, hourOfDay, minute, second) -> {
|
||||||
|
Date eventTime = new Date(runAt);
|
||||||
|
eventTime.setHours(hourOfDay);
|
||||||
|
eventTime.setMinutes(minute);
|
||||||
|
runAt = eventTime.getTime();
|
||||||
|
timeButton.setText(DateUtil.timeString(eventTime));
|
||||||
|
},
|
||||||
|
calendar.get(Calendar.HOUR_OF_DAY),
|
||||||
|
calendar.get(Calendar.MINUTE),
|
||||||
|
DateFormat.is24HourFormat(context)
|
||||||
|
);
|
||||||
|
tpd.setThemeDark(true);
|
||||||
|
tpd.dismissOnPause(true);
|
||||||
|
android.app.FragmentManager fm = ((Activity) context).getFragmentManager();
|
||||||
|
tpd.show(fm, "Timepickerdialog");
|
||||||
|
});
|
||||||
|
|
||||||
|
root.addView(dateButton);
|
||||||
|
root.addView(timeButton);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1372,6 +1372,7 @@
|
||||||
<string name="sms_wrongcode">Wrong code. Command cancelled.</string>
|
<string name="sms_wrongcode">Wrong code. Command cancelled.</string>
|
||||||
<string name="notconfigured">Not configured</string>
|
<string name="notconfigured">Not configured</string>
|
||||||
<string name="profileswitchcreated">Profile switch created</string>
|
<string name="profileswitchcreated">Profile switch created</string>
|
||||||
|
<string name="recurringTime">Recurring time</string>
|
||||||
<plurals name="objective_days">
|
<plurals name="objective_days">
|
||||||
<item quantity="one">%1$d day</item>
|
<item quantity="one">%1$d day</item>
|
||||||
<item quantity="other">%1$d days</item>
|
<item quantity="other">%1$d days</item>
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
package info.nightscout.androidaps.plugins.general.automation.triggers;
|
||||||
|
|
||||||
|
import com.squareup.otto.Bus;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.powermock.api.mockito.PowerMockito;
|
||||||
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
|
import info.AAPSMocker;
|
||||||
|
import info.nightscout.androidaps.MainApp;
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
import info.nightscout.androidaps.utils.T;
|
||||||
|
|
||||||
|
import static org.powermock.api.mockito.PowerMockito.when;
|
||||||
|
|
||||||
|
@RunWith(PowerMockRunner.class)
|
||||||
|
@PrepareForTest({MainApp.class, Bus.class, DateUtil.class, GregorianCalendar.class})
|
||||||
|
public class TriggerRecurringTimeTest {
|
||||||
|
|
||||||
|
long now = 1514766900000L;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldRunTest() {
|
||||||
|
|
||||||
|
// limit by validTo
|
||||||
|
TriggerRecurringTime t = new TriggerRecurringTime().hour(1).minute(34).validTo(1);
|
||||||
|
t.setAll(true);
|
||||||
|
Assert.assertFalse(t.shouldRun());
|
||||||
|
|
||||||
|
// scheduled 1 min before
|
||||||
|
t = new TriggerRecurringTime().hour(1).minute(34);
|
||||||
|
t.setAll(true);
|
||||||
|
Assert.assertTrue(t.shouldRun());
|
||||||
|
|
||||||
|
// already run
|
||||||
|
t = new TriggerRecurringTime().hour(1).minute(34).lastRun(now - 1);
|
||||||
|
t.setAll(true);
|
||||||
|
Assert.assertFalse(t.shouldRun());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
String timeJson = "{\"data\":{\"runAt\":1514766840000,\"THURSDAY\":false,\"lastRun\":0,\"SUNDAY\":false,\"recurring\":false,\"TUESDAY\":false,\"FRIDAY\":false,\"minute\":0,\"WEDNESDAY\":false,\"MONDAY\":false,\"hour\":0,\"SATURDAY\":false,\"validTo\":0},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerRecurringTime\"}";
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void toJSONTest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void fromJSONTest() throws JSONException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void mock() {
|
||||||
|
AAPSMocker.mockMainApp();
|
||||||
|
AAPSMocker.mockBus();
|
||||||
|
|
||||||
|
PowerMockito.mockStatic(DateUtil.class);
|
||||||
|
when(DateUtil.now()).thenReturn(now);
|
||||||
|
|
||||||
|
GregorianCalendar calendar = new GregorianCalendar();
|
||||||
|
calendar.setTimeInMillis(now);
|
||||||
|
when(DateUtil.gregorianCalendar()).thenReturn(calendar);
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,24 +38,9 @@ public class TriggerTimeTest {
|
||||||
t = new TriggerTime().runAt(now + T.mins(1).msecs());
|
t = new TriggerTime().runAt(now + T.mins(1).msecs());
|
||||||
Assert.assertFalse(t.shouldRun());
|
Assert.assertFalse(t.shouldRun());
|
||||||
|
|
||||||
// limit by validTo
|
|
||||||
t = new TriggerTime().recurring(true).hour(1).minute(34).validTo(1);
|
|
||||||
t.setAll(true);
|
|
||||||
Assert.assertFalse(t.shouldRun());
|
|
||||||
|
|
||||||
// scheduled 1 min before
|
|
||||||
t = new TriggerTime().recurring(true).hour(1).minute(34);
|
|
||||||
t.setAll(true);
|
|
||||||
Assert.assertTrue(t.shouldRun());
|
|
||||||
|
|
||||||
// already run
|
|
||||||
t = new TriggerTime().recurring(true).hour(1).minute(34).lastRun(now - 1);
|
|
||||||
t.setAll(true);
|
|
||||||
Assert.assertFalse(t.shouldRun());
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String timeJson = "{\"data\":{\"runAt\":1514766840000,\"THURSDAY\":false,\"lastRun\":0,\"SUNDAY\":false,\"recurring\":false,\"TUESDAY\":false,\"FRIDAY\":false,\"minute\":0,\"WEDNESDAY\":false,\"MONDAY\":false,\"hour\":0,\"SATURDAY\":false,\"validTo\":0},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime\"}";
|
String timeJson = "{\"data\":{\"runAt\":1514766840000,\"lastRun\":0},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime\"}";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void toJSONTest() {
|
public void toJSONTest() {
|
||||||
|
@ -69,7 +54,6 @@ public class TriggerTimeTest {
|
||||||
|
|
||||||
TriggerTime t2 = (TriggerTime) Trigger.instantiate(new JSONObject(t.toJSON()));
|
TriggerTime t2 = (TriggerTime) Trigger.instantiate(new JSONObject(t.toJSON()));
|
||||||
Assert.assertEquals(now - T.mins(1).msecs(), t2.getRunAt());
|
Assert.assertEquals(now - T.mins(1).msecs(), t2.getRunAt());
|
||||||
Assert.assertEquals(false, t2.isRecurring());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
|
|
Loading…
Reference in a new issue