TriggerProfilePercent

This commit is contained in:
Milos Kozak 2019-04-21 22:32:06 +02:00
parent e679f5eaff
commit 42cd2ddaa3
6 changed files with 354 additions and 0 deletions

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.R;
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.TriggerIob;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerProfilePercent;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerRecurringTime;
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime;
@ -34,6 +35,7 @@ public class ChooseTriggerDialog extends DialogFragment {
add(new TriggerRecurringTime());
add(new TriggerBg());
add(new TriggerIob());
add(new TriggerProfilePercent());
}};
private Unbinder mUnbinder;

View file

@ -0,0 +1,58 @@
package info.nightscout.androidaps.plugins.general.automation.elements;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.LinearLayout;
import java.text.DecimalFormat;
import info.nightscout.androidaps.utils.NumberPicker;
public class InputPercent extends Element {
final TextWatcher textWatcher = new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
value = Math.max(value, 0d);
value = Math.min(value, 500d);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
private double value;
public InputPercent() {
super();
value = 100d;
}
public InputPercent(InputPercent another) {
super();
value = another.getValue();
}
@Override
public void addToLayout(LinearLayout root) {
NumberPicker numberPicker = new NumberPicker(root.getContext(), null);
numberPicker.setParams(100d, 0d, 500d, 10d, new DecimalFormat("0"), true, textWatcher);
numberPicker.setValue(value);
numberPicker.setOnValueChangedListener(value -> this.value = value);
root.addView(numberPicker);
}
public double getValue() {
return value;
}
public InputPercent setValue(double value) {
this.value = value;
return this;
}
}

View file

@ -0,0 +1,149 @@
package info.nightscout.androidaps.plugins.general.automation.triggers;
import android.support.v4.app.FragmentManager;
import android.widget.LinearLayout;
import com.google.common.base.Optional;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
import info.nightscout.androidaps.plugins.general.automation.elements.InputPercent;
import info.nightscout.androidaps.plugins.general.automation.elements.Label;
import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.JsonHelper;
import info.nightscout.androidaps.utils.T;
public class TriggerProfilePercent extends Trigger {
private static Logger log = LoggerFactory.getLogger(L.AUTOMATION);
private InputPercent pct = new InputPercent();
private Comparator comparator = new Comparator();
public TriggerProfilePercent() {
super();
}
private TriggerProfilePercent(TriggerProfilePercent triggerProfilePercent) {
super();
pct = new InputPercent(triggerProfilePercent.pct);
comparator = new Comparator(triggerProfilePercent.comparator);
lastRun = triggerProfilePercent.lastRun;
}
public double getValue() {
return pct.getValue();
}
public Comparator getComparator() {
return comparator;
}
public long getLastRun() {
return lastRun;
}
@Override
public synchronized boolean shouldRun() {
if (lastRun > DateUtil.now() - T.mins(5).msecs())
return false;
Profile profile = ProfileFunctions.getInstance().getProfile();
if (profile == null && comparator.getValue().equals(Comparator.Compare.IS_NOT_AVAILABLE)) {
if (L.isEnabled(L.AUTOMATION))
log.debug("Ready for execution: " + friendlyDescription());
return true;
}
if (profile == null)
return false;
boolean doRun = comparator.getValue().check((double) profile.getPercentage(), pct.getValue());
if (doRun) {
if (L.isEnabled(L.AUTOMATION))
log.debug("Ready for execution: " + friendlyDescription());
return true;
}
return false;
}
@Override
public synchronized String toJSON() {
JSONObject o = new JSONObject();
try {
o.put("type", TriggerProfilePercent.class.getName());
JSONObject data = new JSONObject();
data.put("percentage", pct.getValue());
data.put("lastRun", lastRun);
data.put("comparator", comparator.getValue().toString());
o.put("data", data);
} catch (JSONException e) {
e.printStackTrace();
}
return o.toString();
}
@Override
Trigger fromJSON(String data) {
try {
JSONObject d = new JSONObject(data);
pct.setValue(JsonHelper.safeGetDouble(d, "percentage"));
lastRun = JsonHelper.safeGetLong(d, "lastRun");
comparator.setValue(Comparator.Compare.valueOf(JsonHelper.safeGetString(d, "comparator")));
} catch (Exception e) {
e.printStackTrace();
}
return this;
}
@Override
public int friendlyName() {
return R.string.profilepercentage;
}
@Override
public String friendlyDescription() {
return MainApp.gs(R.string.percentagecompared, MainApp.gs(comparator.getValue().getStringRes()), (int) pct.getValue());
}
@Override
public Optional<Integer> icon() {
return Optional.of(R.drawable.remove);
}
@Override
public Trigger duplicate() {
return new TriggerProfilePercent(this);
}
TriggerProfilePercent setValue(double value) {
pct.setValue(value);
return this;
}
TriggerProfilePercent lastRun(long lastRun) {
this.lastRun = lastRun;
return this;
}
TriggerProfilePercent comparator(Comparator.Compare compare) {
this.comparator = new Comparator().setValue(compare);
return this;
}
@Override
public void generateDialog(LinearLayout root, FragmentManager fragmentManager) {
new LayoutBuilder()
.add(comparator)
.add(new Label(MainApp.gs(R.string.percent_u), "", pct))
.build(root);
}
}

View file

@ -1335,6 +1335,7 @@
<string name="glucoseisnotavailable">Glucose is not available</string>
<string name="glucosecomparedmgdl">Glucose %1$s %2$.0f %3$s</string>
<string name="glucosecomparedmmol">Glucose %1$s %2$.1f %3$s</string>
<string name="percentagecompared">Profile pct %1$s %2$d</string>
<string name="iobcompared">IOB %1$s %2$.1f</string>
<string name="and">And</string>
<string name="or">Or</string>
@ -1392,6 +1393,8 @@
<string name="notification">Notification</string>
<string name="notification_message">Notification: %1$s</string>
<string name="message_short">Msg:</string>
<string name="profilepercentage">Profile percentage</string>
<string name="percent_u">Percent [%]:</string>
<plurals name="objective_days">
<item quantity="one">%1$d day</item>

View file

@ -0,0 +1,29 @@
package info.nightscout.androidaps.plugins.general.automation.elements;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import info.nightscout.androidaps.MainApp;
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class})
public class InputPercentTest {
@Test
public void textWatcherTest() {
InputPercent t = new InputPercent().setValue(530d);
t.textWatcher.beforeTextChanged(null, 0, 0, 0);
t.textWatcher.onTextChanged(null, 0, 0, 0);
t.textWatcher.afterTextChanged(null);
Assert.assertEquals(500d, t.getValue(), 0.01d);
}
@Test
public void getSetValueTest() {
InputPercent i = new InputPercent().setValue(10d);
Assert.assertEquals(10d, i.getValue(), 0.01d);
}
}

View file

@ -0,0 +1,113 @@
package info.nightscout.androidaps.plugins.general.automation.triggers;
import com.google.common.base.Optional;
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 info.AAPSMocker;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator;
import info.nightscout.androidaps.utils.DateUtil;
import static org.powermock.api.mockito.PowerMockito.when;
@RunWith(PowerMockRunner.class)
@PrepareForTest({MainApp.class, Bus.class, ProfileFunctions.class, DateUtil.class, L.class})
public class TriggerProfilePercentTest {
private long now = 1514766900000L;
@Test
public void shouldRunTest() {
TriggerProfilePercent t = new TriggerProfilePercent().setValue(101d).comparator(Comparator.Compare.IS_EQUAL);
Assert.assertFalse(t.shouldRun());
t = new TriggerProfilePercent().setValue(100d).comparator(Comparator.Compare.IS_EQUAL);
Assert.assertTrue(t.shouldRun());
t = new TriggerProfilePercent().setValue(100d).comparator(Comparator.Compare.IS_EQUAL_OR_GREATER);
Assert.assertTrue(t.shouldRun());
t = new TriggerProfilePercent().setValue(90d).comparator(Comparator.Compare.IS_EQUAL_OR_GREATER);
Assert.assertTrue(t.shouldRun());
t = new TriggerProfilePercent().setValue(100d).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER);
Assert.assertTrue(t.shouldRun());
t = new TriggerProfilePercent().setValue(101d).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER);
Assert.assertTrue(t.shouldRun());
t = new TriggerProfilePercent().setValue(215d).comparator(Comparator.Compare.IS_EQUAL);
Assert.assertFalse(t.shouldRun());
t = new TriggerProfilePercent().setValue(110d).comparator(Comparator.Compare.IS_EQUAL_OR_GREATER);
Assert.assertFalse(t.shouldRun());
t = new TriggerProfilePercent().setValue(90d).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER);
Assert.assertFalse(t.shouldRun());
// already run
t = new TriggerProfilePercent().setValue(101d).comparator(Comparator.Compare.IS_EQUAL).lastRun(now - 1);
Assert.assertFalse(t.shouldRun());
}
@Test
public void copyConstructorTest() {
TriggerProfilePercent t = new TriggerProfilePercent().setValue(213).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER);
TriggerProfilePercent t1 = (TriggerProfilePercent) t.duplicate();
Assert.assertEquals(213d, t1.getValue(), 0.01d);
Assert.assertEquals(Comparator.Compare.IS_EQUAL_OR_LESSER, t.getComparator().getValue());
}
@Test
public void executeTest() {
TriggerProfilePercent t = new TriggerProfilePercent().setValue(213).comparator(Comparator.Compare.IS_EQUAL_OR_LESSER);
t.executed(1);
Assert.assertEquals(1L, t.getLastRun());
}
private String bgJson = "{\"data\":{\"comparator\":\"IS_EQUAL\",\"lastRun\":0,\"percentage\":110},\"type\":\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerProfilePercent\"}";
@Test
public void toJSONTest() {
TriggerProfilePercent t = new TriggerProfilePercent().setValue(110d).comparator(Comparator.Compare.IS_EQUAL);
Assert.assertEquals(bgJson, t.toJSON());
}
@Test
public void fromJSONTest() throws JSONException {
TriggerProfilePercent t = new TriggerProfilePercent().setValue(120d).comparator(Comparator.Compare.IS_EQUAL);
TriggerProfilePercent t2 = (TriggerProfilePercent) Trigger.instantiate(new JSONObject(t.toJSON()));
Assert.assertEquals(Comparator.Compare.IS_EQUAL, t2.getComparator().getValue());
Assert.assertEquals(120d, t2.getValue(), 0.01d);
}
@Test
public void iconTest() {
Assert.assertEquals(Optional.of(R.drawable.remove), new TriggerProfilePercent().icon());
}
@Test
public void friendlyNameTest() {
Assert.assertEquals(R.string.profilepercentage, new TriggerProfilePercent().friendlyName()); // not mocked
}
@Before
public void mock() {
AAPSMocker.mockMainApp();
AAPSMocker.mockBus();
AAPSMocker.mockProfileFunctions();
AAPSMocker.mockL();
PowerMockito.mockStatic(DateUtil.class);
when(DateUtil.now()).thenReturn(now);
}
}