TriggerBg
This commit is contained in:
parent
ca7e9d2a7f
commit
2bf07eb0d4
9 changed files with 503 additions and 5 deletions
|
@ -1,9 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||
import info.nightscout.androidaps.interfaces.PluginType;
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.Action;
|
||||
|
||||
public class AutomationPlugin extends PluginBase {
|
||||
|
||||
|
@ -15,6 +19,8 @@ public class AutomationPlugin extends PluginBase {
|
|||
return plugin;
|
||||
}
|
||||
|
||||
List<Action> actions = new ArrayList<>();
|
||||
|
||||
private AutomationPlugin() {
|
||||
super(new PluginDescription()
|
||||
.mainType(PluginType.GENERAL)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
public abstract class Action {
|
||||
|
||||
abstract void doAction();
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AutomationEvent {
|
||||
|
||||
Trigger trigger;
|
||||
List<Action> actions = new ArrayList<>();
|
||||
|
||||
AutomationEvent() {
|
||||
}
|
||||
}
|
|
@ -5,17 +5,26 @@ import org.json.JSONObject;
|
|||
|
||||
abstract class Trigger {
|
||||
|
||||
protected static final int ISLOWER = -2;
|
||||
protected static final int ISEQUALORLOWER = -1;
|
||||
protected static final int ISEQUAL = 0;
|
||||
protected static final int ISEQUALORGREATER = 1;
|
||||
protected static final int ISGREATER = 2;
|
||||
|
||||
protected static final int NOTAVAILABLE = 10;
|
||||
|
||||
Trigger() {
|
||||
}
|
||||
|
||||
Trigger(String js) {
|
||||
fromJSON(js);
|
||||
}
|
||||
|
||||
abstract boolean shouldRun();
|
||||
|
||||
abstract String toJSON();
|
||||
|
||||
abstract Trigger fromJSON(String data);
|
||||
|
||||
void notifyAboutRun(long time) {
|
||||
}
|
||||
|
||||
static Trigger instantiate(JSONObject object) {
|
||||
try {
|
||||
String type = object.getString("type");
|
||||
|
@ -27,6 +36,6 @@ abstract class Trigger {
|
|||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
|
||||
public class TriggerBg extends Trigger {
|
||||
|
||||
double threshold;
|
||||
int comparator = ISEQUAL;
|
||||
String units = ProfileFunctions.getInstance().getProfileUnits();
|
||||
|
||||
@Override
|
||||
synchronized boolean shouldRun() {
|
||||
GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData();
|
||||
|
||||
if (glucoseStatus == null && comparator == NOTAVAILABLE)
|
||||
return true;
|
||||
if (glucoseStatus == null)
|
||||
return false;
|
||||
|
||||
switch (comparator) {
|
||||
case ISLOWER:
|
||||
return glucoseStatus.glucose < Profile.toMgdl(threshold, units);
|
||||
case ISEQUALORLOWER:
|
||||
return glucoseStatus.glucose <= Profile.toMgdl(threshold, units);
|
||||
case ISEQUAL:
|
||||
return glucoseStatus.glucose == Profile.toMgdl(threshold, units);
|
||||
case ISEQUALORGREATER:
|
||||
return glucoseStatus.glucose >= Profile.toMgdl(threshold, units);
|
||||
case ISGREATER:
|
||||
return glucoseStatus.glucose > Profile.toMgdl(threshold, units);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
synchronized String toJSON() {
|
||||
JSONObject o = new JSONObject();
|
||||
try {
|
||||
o.put("type", TriggerBg.class.getName());
|
||||
JSONObject data = new JSONObject();
|
||||
data.put("threshold", threshold);
|
||||
data.put("comparator", comparator);
|
||||
data.put("units", units);
|
||||
o.put("data", data.toString());
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return o.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
Trigger fromJSON(String data) {
|
||||
try {
|
||||
JSONObject d = new JSONObject(data);
|
||||
threshold = JsonHelper.safeGetDouble(d, "threshold");
|
||||
comparator = JsonHelper.safeGetInt(d, "comparator");
|
||||
units = JsonHelper.safeGetString(d, "units");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBg threshold(double threshold) {
|
||||
this.threshold = threshold;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBg comparator(int comparator) {
|
||||
this.comparator = comparator;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerBg units(String units) {
|
||||
this.units = units;
|
||||
return this;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.JsonHelper;
|
||||
import info.nightscout.utils.T;
|
||||
|
||||
public class TriggerTime extends Trigger {
|
||||
|
||||
long lastRun;
|
||||
|
||||
// Single execution
|
||||
long runAt;
|
||||
|
||||
// Recurring
|
||||
boolean recurring;
|
||||
boolean monday = true;
|
||||
boolean tuesday = true;
|
||||
boolean wednesday = true;
|
||||
boolean thursday = true;
|
||||
boolean friday = true;
|
||||
boolean saturday = true;
|
||||
boolean sunday = true;
|
||||
int hour;
|
||||
int minute;
|
||||
|
||||
long validTo;
|
||||
|
||||
@Override
|
||||
boolean shouldRun() {
|
||||
if (recurring) {
|
||||
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 (monday && scheduledDayOfWeek == Calendar.MONDAY ||
|
||||
tuesday && scheduledDayOfWeek == Calendar.TUESDAY ||
|
||||
wednesday && scheduledDayOfWeek == Calendar.WEDNESDAY ||
|
||||
thursday && scheduledDayOfWeek == Calendar.THURSDAY ||
|
||||
friday && scheduledDayOfWeek == Calendar.FRIDAY ||
|
||||
saturday && scheduledDayOfWeek == Calendar.SATURDAY ||
|
||||
sunday && scheduledDayOfWeek == Calendar.SUNDAY) {
|
||||
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
|
||||
String toJSON() {
|
||||
JSONObject object = new JSONObject();
|
||||
JSONObject data = new JSONObject();
|
||||
try {
|
||||
data.put("lastRun", lastRun);
|
||||
data.put("runAt", runAt);
|
||||
data.put("recurring", recurring);
|
||||
data.put("monday", monday);
|
||||
data.put("tuesday", tuesday);
|
||||
data.put("wednesday", wednesday);
|
||||
data.put("thursday", thursday);
|
||||
data.put("friday", friday);
|
||||
data.put("saturday", saturday);
|
||||
data.put("sunday", sunday);
|
||||
data.put("hour", hour);
|
||||
data.put("minute", minute);
|
||||
data.put("validTo", validTo);
|
||||
object.put("type", TriggerTime.class.getName());
|
||||
object.put("data", data.toString());
|
||||
} 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");
|
||||
runAt = JsonHelper.safeGetLong(o, "runAt");
|
||||
recurring = JsonHelper.safeGetBoolean(o, "recurring");
|
||||
monday = JsonHelper.safeGetBoolean(o, "monday");
|
||||
tuesday = JsonHelper.safeGetBoolean(o, "tuesday");
|
||||
wednesday = JsonHelper.safeGetBoolean(o, "wednesday");
|
||||
thursday = JsonHelper.safeGetBoolean(o, "thursday");
|
||||
friday = JsonHelper.safeGetBoolean(o, "friday");
|
||||
saturday = JsonHelper.safeGetBoolean(o, "saturday");
|
||||
sunday = JsonHelper.safeGetBoolean(o, "sunday");
|
||||
hour = JsonHelper.safeGetInt(o, "hour");
|
||||
minute = JsonHelper.safeGetInt(o, "minute");
|
||||
validTo = JsonHelper.safeGetLong(o, "validTo");
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
void notifyAboutRun(long time) {
|
||||
lastRun = time;
|
||||
}
|
||||
|
||||
TriggerTime lastRun(long lastRun) {
|
||||
this.lastRun = lastRun;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime runAt(long runAt) {
|
||||
this.runAt = runAt;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime recurring(boolean recurring) {
|
||||
this.recurring = recurring;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime monday(boolean monday) {
|
||||
this.monday = monday;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime tuesday(boolean tuesday) {
|
||||
this.tuesday = tuesday;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime wednesday(boolean wednesday) {
|
||||
this.wednesday = wednesday;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime thursday(boolean thursday) {
|
||||
this.thursday = thursday;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime friday(boolean friday) {
|
||||
this.friday = friday;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime saturday(boolean saturday) {
|
||||
this.saturday = saturday;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime sunday(boolean sunday) {
|
||||
this.sunday = sunday;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime validTo(long validTo) {
|
||||
this.validTo = validTo;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime hour(int hour) {
|
||||
this.hour = hour;
|
||||
return this;
|
||||
}
|
||||
|
||||
TriggerTime minute(int minute) {
|
||||
this.minute = minute;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
|
@ -183,4 +183,8 @@ public class DateUtil {
|
|||
public static long roundDateToSec(long date) {
|
||||
return date - date % 1000;
|
||||
}
|
||||
|
||||
public static GregorianCalendar gregorianCalendar() {
|
||||
return new GregorianCalendar();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
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.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.AAPSMocker;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSSgv;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
import info.nightscout.utils.T;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({MainApp.class, Bus.class, ProfileFunctions.class, DateUtil.class})
|
||||
public class TriggerBgTest {
|
||||
|
||||
@Test
|
||||
public void shouldRunTest() {
|
||||
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(generateOneCurrentRecordBgData());
|
||||
|
||||
TriggerBg t = new TriggerBg().units(Constants.MMOL).threshold(4.1d).comparator(Trigger.ISEQUAL);
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(214).comparator(Trigger.ISEQUAL);
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(214).comparator(Trigger.ISEQUALORGREATER);
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(214).comparator(Trigger.ISEQUALORLOWER);
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(215).comparator(Trigger.ISEQUAL);
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(215).comparator(Trigger.ISEQUALORLOWER);
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(215).comparator(Trigger.ISEQUALORGREATER);
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(213).comparator(Trigger.ISEQUALORGREATER);
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(213).comparator(Trigger.ISEQUALORLOWER);
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
|
||||
when(MainApp.getDbHelper().getBgreadingsDataFromTime(anyLong(), anyBoolean())).thenReturn(new ArrayList<>());
|
||||
t = new TriggerBg().units(Constants.MGDL).threshold(213).comparator(Trigger.ISEQUALORLOWER);
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
t = new TriggerBg().comparator(Trigger.NOTAVAILABLE);
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
}
|
||||
|
||||
String bgJson = "{\"data\":\"{\\\"comparator\\\":0,\\\"threshold\\\":4.1,\\\"units\\\":\\\"mmol\\\"}\",\"type\":\"info.nightscout.androidaps.plugins.general.automation.actions.TriggerBg\"}";
|
||||
|
||||
@Test
|
||||
public void toJSONTest() {
|
||||
TriggerBg t = new TriggerBg().units(Constants.MMOL).threshold(4.1d).comparator(Trigger.ISEQUAL);
|
||||
Assert.assertEquals(bgJson, t.toJSON());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromJSONTest() throws JSONException {
|
||||
TriggerBg t = new TriggerBg().units(Constants.MMOL).threshold(4.1d).comparator(Trigger.ISEQUAL);
|
||||
|
||||
TriggerBg t2 = (TriggerBg) Trigger.instantiate(new JSONObject(t.toJSON()));
|
||||
Assert.assertEquals(Trigger.ISEQUAL, t2.comparator);
|
||||
Assert.assertEquals(4.1d, t2.threshold, 0.01d);
|
||||
Assert.assertEquals(Constants.MMOL, t2.units);
|
||||
}
|
||||
|
||||
@Before
|
||||
public void mock() {
|
||||
AAPSMocker.mockMainApp();
|
||||
AAPSMocker.mockBus();
|
||||
AAPSMocker.mockDatabaseHelper();
|
||||
AAPSMocker.mockProfileFunctions();
|
||||
|
||||
PowerMockito.mockStatic(DateUtil.class);
|
||||
when(DateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs());
|
||||
|
||||
}
|
||||
|
||||
List<BgReading> generateOneCurrentRecordBgData() {
|
||||
List<BgReading> list = new ArrayList<>();
|
||||
try {
|
||||
list.add(new BgReading(new NSSgv(new JSONObject("{\"mgdl\":214,\"mills\":1514766900000,\"direction\":\"Flat\"}"))));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
package info.nightscout.androidaps.plugins.general.automation.actions;
|
||||
|
||||
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.utils.DateUtil;
|
||||
import info.nightscout.utils.T;
|
||||
|
||||
import static org.powermock.api.mockito.PowerMockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({MainApp.class, Bus.class, DateUtil.class, GregorianCalendar.class})
|
||||
public class TriggerTimeTest {
|
||||
|
||||
long now = 1514766900000L;
|
||||
|
||||
@Test
|
||||
public void shouldRunTest() {
|
||||
|
||||
// scheduled 1 min before
|
||||
TriggerTime t = new TriggerTime().runAt(now - T.mins(1).msecs());
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
// scheduled 1 min in the future
|
||||
t = new TriggerTime().runAt(now + T.mins(1).msecs());
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
|
||||
// limit by validTo
|
||||
t = new TriggerTime().recurring(true).hour(1).minute(34).validTo(1);
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
|
||||
// scheduled 1 min before
|
||||
t = new TriggerTime().recurring(true).hour(1).minute(34);
|
||||
Assert.assertTrue(t.shouldRun());
|
||||
|
||||
// already run
|
||||
t = new TriggerTime().recurring(true).hour(1).minute(34).lastRun(now - 1);
|
||||
Assert.assertFalse(t.shouldRun());
|
||||
|
||||
}
|
||||
|
||||
String timeJson = "{\"data\":\"{\\\"saturday\\\":true,\\\"runAt\\\":1514766840000,\\\"lastRun\\\":0,\\\"recurring\\\":false,\\\"thursday\\\":true,\\\"minute\\\":0,\\\"sunday\\\":true,\\\"tuesday\\\":true,\\\"hour\\\":0,\\\"wednesday\\\":true,\\\"friday\\\":true,\\\"monday\\\":true,\\\"validTo\\\":0}\",\"type\":\"info.nightscout.androidaps.plugins.general.automation.actions.TriggerTime\"}";
|
||||
|
||||
@Test
|
||||
public void toJSONTest() {
|
||||
TriggerTime t = new TriggerTime().runAt(now - T.mins(1).msecs());
|
||||
Assert.assertEquals(timeJson, t.toJSON());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void fromJSONTest() throws JSONException {
|
||||
TriggerTime t = new TriggerTime().runAt(now - T.mins(1).msecs());
|
||||
|
||||
TriggerTime t2 = (TriggerTime) Trigger.instantiate(new JSONObject(t.toJSON()));
|
||||
Assert.assertEquals(now - T.mins(1).msecs(), t2.runAt);
|
||||
Assert.assertEquals(false, t2.recurring);
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue