diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPlugin.java index 5c24427e40..d7feca452f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPlugin.java @@ -18,14 +18,11 @@ 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.notifications.Notification; -import info.nightscout.androidaps.utils.T; -/** - * Created by Rumen on 31.10.2018. - */ 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 int minutesToChange = 0; static DstHelperPlugin plugin = null; @@ -45,53 +42,19 @@ public class DstHelperPlugin extends PluginBase implements ConstraintsInterface ); } - public int dstTest(Calendar c) throws Exception { -// c = Calendar.getInstance(TimeZone.getDefault()); -// c = Calendar.getInstance(TimeZone.getTimeZone("Australia/Lord_Howe")); -// c.setTimeInMillis(DateUtil.fromISODateString("2018-10-07T01:00:00Z").getTime()); - 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; - + public static boolean wasDST(Calendar now) { + Calendar ago = (Calendar) now.clone(); + ago.add(Calendar.HOUR, DISABLE_TIMEFRAME_HOURS); + return now.get(Calendar.DST_OFFSET) != ago.get(Calendar.DST_OFFSET); } - //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 public Constraint isLoopInvocationAllowed(Constraint value) { @@ -101,34 +64,31 @@ public class DstHelperPlugin extends PluginBase implements ConstraintsInterface return value; } - try { - this.dstTest(Calendar.getInstance()); - } catch (Exception e) { - e.printStackTrace(); - } - if (this.minutesToChange <= 180 && 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"); + Calendar cal = Calendar.getInstance(); - } catch (Exception e) { - e.printStackTrace(); - } - value.set(false, "DST in 90 minutes or less", this); - } else if (minutesToChange <= 24 * T.hours(1).mins() && minutesToChange > 0) { + if (willBeDST(cal)) { 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; } - // display warning - void warnUser(int id, String warningText) { + private void warnUser(int id, String warningText) { Notification notification = new Notification(id, warningText, Notification.LOW); MainApp.bus().post(new EventNewNotification(notification)); } - } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cb8329872e..2a7021f6b8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1319,7 +1319,7 @@ smbmaxminutes Dayligh Saving time Dayligh Saving time change in 24h or less - Dayligh Saving time change in less than 3 hours - Closed loop diabled + Dayligh Saving time change less than 3 hours ago - Closed loop diabled internal storage constraint Free at least %1$d MB from internal storage! Loop disabled! Wrong format diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPluginTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPluginTest.java index 2f5bf9bffe..303d63d9c9 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPluginTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/constraints/dstHelper/DstHelperPluginTest.java @@ -9,7 +9,11 @@ import org.junit.runner.RunWith; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import java.text.DateFormat; +import java.text.SimpleDateFormat; import java.util.Calendar; +import java.util.Date; +import java.util.Locale; import java.util.TimeZone; import info.AAPSMocker; @@ -27,39 +31,46 @@ public class DstHelperPluginTest { public void runTest() throws Exception { AAPSMocker.mockMainApp(); 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()); - minutesLeftToChange = plugin.dstTest(c); - Assert.assertEquals(0, minutesLeftToChange); + TimeZone tz = TimeZone.getTimeZone("Europe/Rome"); + TimeZone.setDefault(tz); + 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); } } \ No newline at end of file