From cdd3c259296976a945a8a834da7c7479e1f3992a Mon Sep 17 00:00:00 2001 From: Adrian AndroidAPS Date: Thu, 28 Mar 2019 17:25:57 +0100 Subject: [PATCH 1/3] only run DST helper on certain pumps --- .../androidaps/interfaces/PumpInterface.java | 1 + .../constraints/dstHelper/DstHelperPlugin.java | 11 ++++++++++- .../androidaps/plugins/pump/combo/ComboPlugin.java | 5 +++++ .../plugins/pump/danaR/AbstractDanaRPlugin.java | 8 ++++++++ .../androidaps/plugins/pump/danaRS/DanaRSPlugin.java | 5 +++++ .../plugins/pump/insight/LocalInsightPlugin.java | 5 +++++ .../androidaps/plugins/pump/mdi/MDIPlugin.java | 5 +++++ .../plugins/pump/virtual/VirtualPumpPlugin.java | 5 +++++ 8 files changed, 44 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java index 7e8f2ef181..3690312cf8 100644 --- a/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java +++ b/app/src/main/java/info/nightscout/androidaps/interfaces/PumpInterface.java @@ -65,6 +65,7 @@ public interface PumpInterface { PumpEnactResult loadTDDs(); + public boolean canHandleDST(); List getCustomActions(); 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 2862cc3d7a..5c24427e40 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 @@ -12,8 +12,10 @@ import info.nightscout.androidaps.interfaces.ConstraintsInterface; import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginDescription; import info.nightscout.androidaps.interfaces.PluginType; +import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.logging.L; 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; @@ -92,12 +94,19 @@ public class DstHelperPlugin extends PluginBase implements ConstraintsInterface //Return false if time to DST change is less than 91 and positive @Override public Constraint isLoopInvocationAllowed(Constraint value) { + + PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); + if (pump == null || pump.canHandleDST()) { + log.debug("Pump can handle DST"); + return value; + } + try { this.dstTest(Calendar.getInstance()); } catch (Exception e) { e.printStackTrace(); } - if (this.minutesToChange <= 90 && minutesToChange > 0 && value.value()) { + if (this.minutesToChange <= 180 && minutesToChange > 0 && value.value()) { try { LoopPlugin loopPlugin = LoopPlugin.getPlugin(); if (loopPlugin.suspendedTo() == 0L) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java index a84e3db9a8..557ba42168 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/combo/ComboPlugin.java @@ -1391,4 +1391,9 @@ public class ComboPlugin extends PluginBase implements PumpInterface, Constraint } + @Override + public boolean canHandleDST() { + return false; + } + } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java index d6f25f9c02..749307e1a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaR/AbstractDanaRPlugin.java @@ -488,4 +488,12 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte } + @Override + public boolean canHandleDST() { + return false; + } + + + + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java index d2eb132f61..ddbb8547ae 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/danaRS/DanaRSPlugin.java @@ -827,4 +827,9 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte } + @Override + public boolean canHandleDST() { + return false; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java index 22b329edbb..ccc38c1b9b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/insight/LocalInsightPlugin.java @@ -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); new Handler(Looper.getMainLooper()).post(() -> MainApp.bus().post(new EventNewNotification(notification))); } + + @Override + public boolean canHandleDST() { + return true; + } } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java index bdd060183b..89d1184581 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/mdi/MDIPlugin.java @@ -260,4 +260,9 @@ public class MDIPlugin extends PluginBase implements PumpInterface { } + @Override + public boolean canHandleDST() { + return true; + } + } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java index e60cd78a64..461f71c31d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/virtual/VirtualPumpPlugin.java @@ -455,6 +455,11 @@ public class VirtualPumpPlugin extends PluginBase implements PumpInterface { return pumpType; } + @Override + public boolean canHandleDST() { + return true; + } + public void refreshConfiguration() { String pumptype = SP.getString(R.string.key_virtualpump_type, "Generic AAPS"); From d856b87703149cfdd64dfe760513296a86972443 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Thu, 28 Mar 2019 19:38:58 +0100 Subject: [PATCH 2/3] rewrite DST logic --- .../dstHelper/DstHelperPlugin.java | 102 ++++++------------ app/src/main/res/values/strings.xml | 2 +- .../dstHelper/DstHelperPluginTest.java | 73 +++++++------ 3 files changed, 74 insertions(+), 103 deletions(-) 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 From ebc8303cc662a46a6144ebaefbc214362d48e767 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Thu, 28 Mar 2019 22:13:57 +0100 Subject: [PATCH 3/3] isSuspended -> is NOT suspended --- .../plugins/constraints/dstHelper/DstHelperPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 d7feca452f..ec3ef44881 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 @@ -77,7 +77,7 @@ public class DstHelperPlugin extends PluginBase implements ConstraintsInterface if (wasDST(cal)) { LoopPlugin loopPlugin = LoopPlugin.getPlugin(); - if (loopPlugin.isSuspended()) { + if (!loopPlugin.isSuspended()) { warnUser(Notification.DST_LOOP_DISABLED, MainApp.gs(R.string.dst_loop_disabled_warning)); } else { log.debug("Loop already suspended");