Merge pull request #1692 from MilosKozak/dst-work
only run DST helper on certain pumps
This commit is contained in:
commit
5ff8dbad47
10 changed files with 117 additions and 103 deletions
|
@ -65,6 +65,7 @@ public interface PumpInterface {
|
||||||
|
|
||||||
PumpEnactResult loadTDDs();
|
PumpEnactResult loadTDDs();
|
||||||
|
|
||||||
|
public boolean canHandleDST();
|
||||||
|
|
||||||
List<CustomAction> getCustomActions();
|
List<CustomAction> getCustomActions();
|
||||||
|
|
||||||
|
|
|
@ -12,18 +12,17 @@ import info.nightscout.androidaps.interfaces.ConstraintsInterface;
|
||||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||||
import info.nightscout.androidaps.interfaces.PluginDescription;
|
import info.nightscout.androidaps.interfaces.PluginDescription;
|
||||||
import info.nightscout.androidaps.interfaces.PluginType;
|
import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
import info.nightscout.androidaps.logging.L;
|
import info.nightscout.androidaps.logging.L;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||||
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||||
import info.nightscout.androidaps.utils.T;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by Rumen on 31.10.2018.
|
|
||||||
*/
|
|
||||||
public class DstHelperPlugin extends PluginBase implements ConstraintsInterface {
|
public class DstHelperPlugin extends PluginBase implements ConstraintsInterface {
|
||||||
|
public static final int DISABLE_TIMEFRAME_HOURS = -3;
|
||||||
|
public static final int WARN_PRIOR_TIMEFRAME_HOURS = 24;
|
||||||
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
|
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
|
||||||
private int minutesToChange = 0;
|
|
||||||
|
|
||||||
static DstHelperPlugin plugin = null;
|
static DstHelperPlugin plugin = null;
|
||||||
|
|
||||||
|
@ -43,83 +42,53 @@ public class DstHelperPlugin extends PluginBase implements ConstraintsInterface
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int dstTest(Calendar c) throws Exception {
|
public static boolean wasDST(Calendar now) {
|
||||||
// c = Calendar.getInstance(TimeZone.getDefault());
|
Calendar ago = (Calendar) now.clone();
|
||||||
// c = Calendar.getInstance(TimeZone.getTimeZone("Australia/Lord_Howe"));
|
ago.add(Calendar.HOUR, DISABLE_TIMEFRAME_HOURS);
|
||||||
// c.setTimeInMillis(DateUtil.fromISODateString("2018-10-07T01:00:00Z").getTime());
|
return now.get(Calendar.DST_OFFSET) != ago.get(Calendar.DST_OFFSET);
|
||||||
long zoneOffset = c.get(Calendar.ZONE_OFFSET);
|
|
||||||
long d1 = c.getTimeInMillis() - zoneOffset;
|
|
||||||
c.setTimeInMillis(d1);
|
|
||||||
int offset1 = c.get(Calendar.DST_OFFSET);
|
|
||||||
|
|
||||||
c.add(Calendar.DATE, 1);
|
|
||||||
long d2 = c.getTimeInMillis();
|
|
||||||
|
|
||||||
int diffInHours = (int) ((d1 - d2) / -T.hours(1).msecs());
|
|
||||||
long offsetDetectedTime = 0;
|
|
||||||
// comparing millis because change can be < 1 hour
|
|
||||||
// log.debug("Starting from: "+startTimeString + " to "+endTimeString);
|
|
||||||
// log.debug("start "+offset1+" end "+c.get(Calendar.DST_OFFSET));
|
|
||||||
if (offset1 != c.get(Calendar.DST_OFFSET)) {
|
|
||||||
//we have a time change in next 24 hours, but when exactly
|
|
||||||
// log.debug("Daylight saving time detected between " + startTimeString + " and " + endTimeString);
|
|
||||||
// log.debug("Diff in hours is: "+diffInHours);
|
|
||||||
c.setTimeInMillis(d1 - zoneOffset);
|
|
||||||
offset1 = c.get(Calendar.DST_OFFSET);
|
|
||||||
for (int i = 0; i <= diffInHours * 4; i++) {
|
|
||||||
|
|
||||||
if (offset1 != c.get(Calendar.DST_OFFSET)) {
|
|
||||||
log.debug("Detected offset in " + ((i / 4) - zoneOffset / T.hours(1).msecs()) + " hours value is " + (offset1 - c.get(Calendar.DST_OFFSET)) / T.mins(1).msecs() + " minutes");
|
|
||||||
offsetDetectedTime = c.getTimeInMillis() - d1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
c.add(Calendar.MINUTE, 15);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
int minutesLeft = (int) ((offsetDetectedTime / T.mins(1).msecs()));
|
|
||||||
/*log.debug("zoneoffset(minutes):"+zoneOffset/T.mins(1).msecs());
|
|
||||||
log.debug("Start offset: "+offset1/T.mins(1).msecs());
|
|
||||||
log.debug("End offset :" + c.get(Calendar.DST_OFFSET)/T.mins(1).msecs());
|
|
||||||
log.debug("Now is:"+startTimeString);
|
|
||||||
log.debug("Detected in(min): "+(offsetDetectedTime/T.mins(1).msecs()));
|
|
||||||
log.debug("Returning value of: " + minutesLeft); */
|
|
||||||
minutesToChange = minutesLeft;
|
|
||||||
return minutesLeft;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Return false if time to DST change is less than 91 and positive
|
public static boolean willBeDST(Calendar now) {
|
||||||
|
Calendar ago = (Calendar) now.clone();
|
||||||
|
ago.add(Calendar.HOUR, WARN_PRIOR_TIMEFRAME_HOURS);
|
||||||
|
return now.get(Calendar.DST_OFFSET) != ago.get(Calendar.DST_OFFSET);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Return false if time to DST change happened in the last 3 hours.
|
||||||
@Override
|
@Override
|
||||||
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
public Constraint<Boolean> isLoopInvocationAllowed(Constraint<Boolean> value) {
|
||||||
try {
|
|
||||||
this.dstTest(Calendar.getInstance());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
if (this.minutesToChange <= 90 && minutesToChange > 0 && value.value()) {
|
|
||||||
try {
|
|
||||||
LoopPlugin loopPlugin = LoopPlugin.getPlugin();
|
|
||||||
if (loopPlugin.suspendedTo() == 0L) {
|
|
||||||
// loopPlugin.suspendTo(System.currentTimeMillis() + minutesToChange * T.mins(1).msecs());
|
|
||||||
warnUser(Notification.DST_LOOP_DISABLED, MainApp.gs(R.string.dst_loop_disabled_warning));
|
|
||||||
} else
|
|
||||||
log.debug("Loop already suspended");
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
|
||||||
e.printStackTrace();
|
if (pump == null || pump.canHandleDST()) {
|
||||||
|
log.debug("Pump can handle DST");
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
value.set(false, "DST in 90 minutes or less", this);
|
|
||||||
} else if (minutesToChange <= 24 * T.hours(1).mins() && minutesToChange > 0) {
|
Calendar cal = Calendar.getInstance();
|
||||||
|
|
||||||
|
if (willBeDST(cal)) {
|
||||||
warnUser(Notification.DST_IN_24H, MainApp.gs(R.string.dst_in_24h_warning));
|
warnUser(Notification.DST_IN_24H, MainApp.gs(R.string.dst_in_24h_warning));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!value.value()) {
|
||||||
|
log.debug("Already not allowed - don't check further");
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wasDST(cal)) {
|
||||||
|
LoopPlugin loopPlugin = LoopPlugin.getPlugin();
|
||||||
|
if (!loopPlugin.isSuspended()) {
|
||||||
|
warnUser(Notification.DST_LOOP_DISABLED, MainApp.gs(R.string.dst_loop_disabled_warning));
|
||||||
|
} else {
|
||||||
|
log.debug("Loop already suspended");
|
||||||
|
}
|
||||||
|
value.set(false, "DST in last 3 hours.", this);
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// display warning
|
private void warnUser(int id, String warningText) {
|
||||||
void warnUser(int id, String warningText) {
|
|
||||||
Notification notification = new Notification(id, warningText, Notification.LOW);
|
Notification notification = new Notification(id, warningText, Notification.LOW);
|
||||||
MainApp.bus().post(new EventNewNotification(notification));
|
MainApp.bus().post(new EventNewNotification(notification));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -1391,4 +1391,9 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canHandleDST() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -488,4 +488,12 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canHandleDST() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -827,4 +827,9 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canHandleDST() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1569,4 +1569,9 @@ public class LocalInsightPlugin extends PluginBase implements PumpInterface, Con
|
||||||
Notification notification = new Notification(Notification.INSIGHT_TIMEOUT_DURING_HANDSHAKE, MainApp.gs(R.string.timeout_during_handshake), Notification.URGENT);
|
Notification notification = new Notification(Notification.INSIGHT_TIMEOUT_DURING_HANDSHAKE, MainApp.gs(R.string.timeout_during_handshake), Notification.URGENT);
|
||||||
new Handler(Looper.getMainLooper()).post(() -> MainApp.bus().post(new EventNewNotification(notification)));
|
new Handler(Looper.getMainLooper()).post(() -> MainApp.bus().post(new EventNewNotification(notification)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canHandleDST() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -260,4 +260,9 @@ public class MDIPlugin extends PluginBase implements PumpInterface {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canHandleDST() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -455,6 +455,11 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface {
|
||||||
return pumpType;
|
return pumpType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canHandleDST() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void refreshConfiguration() {
|
public void refreshConfiguration() {
|
||||||
String pumptype = SP.getString(R.string.key_virtualpump_type, "Generic AAPS");
|
String pumptype = SP.getString(R.string.key_virtualpump_type, "Generic AAPS");
|
||||||
|
|
|
@ -1319,7 +1319,7 @@
|
||||||
<string name="key_smbmaxminutes" translatable="false">smbmaxminutes</string>
|
<string name="key_smbmaxminutes" translatable="false">smbmaxminutes</string>
|
||||||
<string name="dst_plugin_name" translatable="false">Dayligh Saving time</string>
|
<string name="dst_plugin_name" translatable="false">Dayligh Saving time</string>
|
||||||
<string name="dst_in_24h_warning">Dayligh Saving time change in 24h or less</string>
|
<string name="dst_in_24h_warning">Dayligh Saving time change in 24h or less</string>
|
||||||
<string name="dst_loop_disabled_warning">Dayligh Saving time change in less than 3 hours - Closed loop diabled</string>
|
<string name="dst_loop_disabled_warning">Dayligh Saving time change less than 3 hours ago - Closed loop diabled</string>
|
||||||
<string name="storage">internal storage constraint</string>
|
<string name="storage">internal storage constraint</string>
|
||||||
<string name="diskfull">Free at least %1$d MB from internal storage! Loop disabled!</string>
|
<string name="diskfull">Free at least %1$d MB from internal storage! Loop disabled!</string>
|
||||||
<string name="wrongformat">Wrong format</string>
|
<string name="wrongformat">Wrong format</string>
|
||||||
|
|
|
@ -9,7 +9,11 @@ import org.junit.runner.RunWith;
|
||||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||||
import org.powermock.modules.junit4.PowerMockRunner;
|
import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
|
import java.text.DateFormat;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import info.AAPSMocker;
|
import info.AAPSMocker;
|
||||||
|
@ -27,39 +31,46 @@ public class DstHelperPluginTest {
|
||||||
public void runTest() throws Exception {
|
public void runTest() throws Exception {
|
||||||
AAPSMocker.mockMainApp();
|
AAPSMocker.mockMainApp();
|
||||||
AAPSMocker.mockApplicationContext();
|
AAPSMocker.mockApplicationContext();
|
||||||
// test different time zones
|
|
||||||
//Starting with Europe/Sofia
|
|
||||||
Calendar c = Calendar.getInstance(TimeZone.getTimeZone("Europe/Sofia"));
|
|
||||||
c.setTimeInMillis(DateUtil.fromISODateString("2018-10-28T02:00:00Z").getTime());
|
|
||||||
int minutesLeftToChange = plugin.dstTest(c);
|
|
||||||
Assert.assertEquals(60, minutesLeftToChange);
|
|
||||||
c.setTimeInMillis(DateUtil.fromISODateString("2018-03-25T02:00:00Z").getTime());
|
|
||||||
minutesLeftToChange = plugin.dstTest(c);
|
|
||||||
Assert.assertEquals(60, minutesLeftToChange);
|
|
||||||
// try something with half hour somewhere in Australia
|
|
||||||
c = Calendar.getInstance(TimeZone.getTimeZone("Australia/Lord_Howe"));
|
|
||||||
c.setTimeInMillis(DateUtil.fromISODateString("2018-04-01T00:00:00Z").getTime());
|
|
||||||
minutesLeftToChange = plugin.dstTest(c);
|
|
||||||
// try something with half hour somewhere in Australia
|
|
||||||
c = Calendar.getInstance(TimeZone.getTimeZone("Australia/Lord_Howe"));
|
|
||||||
c.setTimeInMillis(DateUtil.fromISODateString("2018-04-01T00:00:00Z").getTime());
|
|
||||||
minutesLeftToChange = plugin.dstTest(c);
|
|
||||||
Assert.assertEquals(90, minutesLeftToChange);
|
|
||||||
c = Calendar.getInstance(TimeZone.getTimeZone("Australia/Lord_Howe"));
|
|
||||||
// and back
|
|
||||||
c.setTimeInMillis(DateUtil.fromISODateString("2018-10-07T00:00:00Z").getTime());
|
|
||||||
minutesLeftToChange = plugin.dstTest(c);
|
|
||||||
Assert.assertEquals(120, minutesLeftToChange);
|
|
||||||
|
|
||||||
c.setTimeInMillis(DateUtil.fromISODateString("2018-10-08T00:00:00Z").getTime());
|
TimeZone tz = TimeZone.getTimeZone("Europe/Rome");
|
||||||
minutesLeftToChange = plugin.dstTest(c);
|
TimeZone.setDefault(tz);
|
||||||
Assert.assertEquals(0, minutesLeftToChange);
|
Calendar cal = Calendar.getInstance(tz, Locale.ITALIAN);
|
||||||
|
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.ITALIAN);
|
||||||
|
Date dateBeforeDST = df.parse("2018-03-25 01:55");
|
||||||
|
cal.setTime(dateBeforeDST);
|
||||||
|
Assert.assertEquals(false, plugin.wasDST(cal));
|
||||||
|
Assert.assertEquals(true, plugin.willBeDST(cal));
|
||||||
|
|
||||||
|
|
||||||
|
TimeZone.setDefault(tz);
|
||||||
|
cal = Calendar.getInstance(tz, Locale.ITALIAN);
|
||||||
|
dateBeforeDST = df.parse("2018-03-25 03:05");
|
||||||
|
cal.setTime(dateBeforeDST);
|
||||||
|
Assert.assertEquals(true, plugin.wasDST(cal));
|
||||||
|
Assert.assertEquals(false, plugin.willBeDST(cal));
|
||||||
|
|
||||||
|
|
||||||
|
TimeZone.setDefault(tz);
|
||||||
|
cal = Calendar.getInstance(tz, Locale.ITALIAN);
|
||||||
|
dateBeforeDST = df.parse("2018-03-25 02:05"); //Cannot happen!!!
|
||||||
|
cal.setTime(dateBeforeDST);
|
||||||
|
Assert.assertEquals(true, plugin.wasDST(cal));
|
||||||
|
Assert.assertEquals(false, plugin.willBeDST(cal));
|
||||||
|
|
||||||
|
TimeZone.setDefault(tz);
|
||||||
|
cal = Calendar.getInstance(tz, Locale.ITALIAN);
|
||||||
|
dateBeforeDST = df.parse("2018-03-25 05:55"); //Cannot happen!!!
|
||||||
|
cal.setTime(dateBeforeDST);
|
||||||
|
Assert.assertEquals(true, plugin.wasDST(cal));
|
||||||
|
Assert.assertEquals(false, plugin.willBeDST(cal));
|
||||||
|
|
||||||
|
TimeZone.setDefault(tz);
|
||||||
|
cal = Calendar.getInstance(tz, Locale.ITALIAN);
|
||||||
|
dateBeforeDST = df.parse("2018-03-25 06:05"); //Cannot happen!!!
|
||||||
|
cal.setTime(dateBeforeDST);
|
||||||
|
Assert.assertEquals(false, plugin.wasDST(cal));
|
||||||
|
Assert.assertEquals(false, plugin.willBeDST(cal));
|
||||||
|
|
||||||
// DST event was 30 mins
|
|
||||||
c.setTimeInMillis(DateUtil.fromISODateString("2018-04-01T02:00:00Z").getTime());
|
|
||||||
minutesLeftToChange = plugin.dstTest(c);
|
|
||||||
// Assert.assertEquals(630, plugin.zoneOffsetInMinutes(c));
|
|
||||||
Assert.assertEquals(0, minutesLeftToChange);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue