From 3dd84220a37b2c2f41400053d11c56e54bebb232 Mon Sep 17 00:00:00 2001 From: jens Date: Sun, 11 Feb 2024 17:25:42 +0100 Subject: [PATCH] date time repetition --- .../java/com/jens/automation2/TimeFrame.java | 6 +- .../receivers/DateTimeListener.java | 143 +++++++++++------- 2 files changed, 90 insertions(+), 59 deletions(-) diff --git a/app/src/main/java/com/jens/automation2/TimeFrame.java b/app/src/main/java/com/jens/automation2/TimeFrame.java index 3163265..76e1070 100644 --- a/app/src/main/java/com/jens/automation2/TimeFrame.java +++ b/app/src/main/java/com/jens/automation2/TimeFrame.java @@ -2,6 +2,7 @@ package com.jens.automation2; import java.sql.Time; import java.util.ArrayList; +import java.util.Collections; public class TimeFrame { @@ -20,18 +21,19 @@ public class TimeFrame public void setDayList(ArrayList dayList) { this.dayList = dayList; + Collections.sort(dayList); } public void setDayListFromString(String dayListString) { -// Log.i("Parsing", "Full string: " + dayListString); char[] dayListCharArray = dayListString.toCharArray(); dayList = new ArrayList(); for(char item : dayListCharArray) { -// Log.i("Parsing", String.valueOf(item)); dayList.add(Integer.parseInt(String.valueOf(item))); } + + Collections.sort(dayList); } public TimeObject getTriggerTimeStart() diff --git a/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java b/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java index d60a7d0..6c800e9 100644 --- a/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java +++ b/app/src/main/java/com/jens/automation2/receivers/DateTimeListener.java @@ -22,6 +22,7 @@ import com.jens.automation2.Trigger.Trigger_Enum; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.Date; public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface @@ -367,14 +368,45 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis } } + static int getNextDayIntForExecution(Trigger trigger) + { + TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2()); + Calendar now = Calendar.getInstance(); + + if(tf.getDayList().contains(now.get(Calendar.DAY_OF_WEEK))) + return now.get(Calendar.DAY_OF_WEEK); + else + { + int dayNumberOfNextExecution = now.get(Calendar.DAY_OF_WEEK); + + while(!tf.getDayList().contains(dayNumberOfNextExecution)) + { + dayNumberOfNextExecution++; + if(dayNumberOfNextExecution > 6) + dayNumberOfNextExecution = 1; + } + + return dayNumberOfNextExecution; + } + } + + static int getDayDelta(Calendar now, int dayNumberOfNextExecution) + { + int result = dayNumberOfNextExecution - now.get(Calendar.DAY_OF_WEEK); + + if(result >= 0) + return result; + else + return 6 + result; + } + @Nullable @RequiresApi(api = Build.VERSION_CODES.N) public static Calendar getNextRepeatedExecution(Trigger trigger) { - Miscellaneous.logEvent("i", "DateTimeListener", "Checking for next repetition execution after " + Miscellaneous.formatDate(repetitionSearchStartPoint.getTime()), 5); + Miscellaneous.logEvent("i", "DateTimeListener", "Checking for next repetition execution after " + Miscellaneous.formatDate(Calendar.getInstance().getTime()), 5); Calendar now = Calendar.getInstance(); - Calendar calculationStart; - TimeObject setTime; + Calendar calculationStart, calSchedule = null; TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2()); if(tf.getRepetition() > 0) @@ -383,34 +415,59 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis Are we inside of the timeframe or outside? Inside -> is this demanded? + Yes: If last execution known, calculate from it If not known, calculate from start of timeframe No: Use end-time and add repetition - Outisde? -> is this demanded? + Outside? -> is this demanded? + Yes: If last execution known, calculate from it If not known, calculate from end of timeframe No: Use start-time and add repetition */ - if(trigger.getParentRule().getLastExecution() != null) - { - calculationStart = trigger.getParentRule().getLastExecution(); - if(areWeInTimeFrame(trigger, new Date()) != trigger.getTriggerParameter()) + if(areWeInTimeFrame(trigger, new Date())) + { + if(trigger.getTriggerParameter()) { - if(trigger.getTriggerParameter()) + if(trigger.getParentRule().getLastExecution() != null) + { + calculationStart = (Calendar) trigger.getParentRule().getLastExecution().clone(); + } + else { calculationStart = (Calendar) now.clone(); calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours()); calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes()); calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds()); calculationStart.set(Calendar.MILLISECOND, 0); - calculationStart.add(Calendar.SECOND, (int) tf.getRepetition()); - - if(calculationStart.getTimeInMillis() < now.getTimeInMillis() && !areWeInTimeFrame(trigger, new Date())) - calculationStart.add(Calendar.DAY_OF_MONTH, 1); + } + long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000; + long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1; + calSchedule = (Calendar) calculationStart.clone(); + calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition())); + } + else + { + calculationStart = (Calendar) now.clone(); + calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStop().getHours()); + calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes()); + calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds()); + calculationStart.set(Calendar.MILLISECOND, 0); + calSchedule = (Calendar) calculationStart.clone(); + calSchedule.add(Calendar.SECOND, (int) tf.getRepetition()); + } + } + else + { + if (!trigger.getTriggerParameter()) + { + if (trigger.getParentRule().getLastExecution() != null) + { + calculationStart = (Calendar) trigger.getParentRule().getLastExecution().clone(); } else { @@ -419,63 +476,35 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes()); calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds()); calculationStart.set(Calendar.MILLISECOND, 0); - calculationStart.add(Calendar.SECOND, (int) tf.getRepetition()); - - if(calculationStart.getTimeInMillis() < now.getTimeInMillis() && areWeInTimeFrame(trigger, new Date())) - calculationStart.add(Calendar.DAY_OF_MONTH, 1); } - } - } - else - { - if(trigger.getTriggerParameter()) - { -// Miscellaneous.logEvent("i", "DateTimeListener", "Chose start of next interval of trigger in rule " + trigger.getParentRule().getName() + " as calculation start.", 5); - setTime = tf.getTriggerTimeStart(); + long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000; + long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1; + calSchedule = (Calendar) calculationStart.clone(); + calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition())); } else { -// Miscellaneous.logEvent("i", "DateTimeListener", "Chose end of next interval of trigger in rule " + trigger.getParentRule().getName() + " as calculation start.", 5); - setTime = tf.getTriggerTimeStop(); + calculationStart = (Calendar) now.clone(); + calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours()); + calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes()); + calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds()); + calculationStart.set(Calendar.MILLISECOND, 0); + calSchedule = (Calendar) calculationStart.clone(); + calSchedule.add(Calendar.SECOND, (int) (tf.getRepetition())); + + if() } - - calculationStart = (Calendar) now.clone(); - calculationStart.set(Calendar.HOUR_OF_DAY, setTime.getHours()); - calculationStart.set(Calendar.MINUTE, setTime.getMinutes()); - calculationStart.set(Calendar.SECOND, setTime.getSeconds()); - calculationStart.add(Calendar.SECOND, (int) tf.getRepetition()); - - if(calculationStart.getTimeInMillis() < now.getTimeInMillis() && areWeInTimeFrame(trigger, new Date())) - calculationStart.add(Calendar.DAY_OF_MONTH, 1); } - calculationStart.set(Calendar.MILLISECOND, 0); - Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "calcStart: " + Miscellaneous.formatDate(calculationStart.getTime()) + ", now: " + Miscellaneous.formatDate(repetitionSearchStartPoint.getTime()), 5); - - Calendar calSchedule; - - if(calculationStart.getTimeInMillis() < now.getTimeInMillis()) - { - long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000; - long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1; - long nextScheduleTimestamp = (calculationStart.getTimeInMillis() / 1000) + (nextExecutionMultiplier * tf.getRepetition()); - calSchedule = Calendar.getInstance(); - calSchedule.setTimeInMillis(nextScheduleTimestamp * 1000); - } - else - { - calSchedule = (Calendar) calculationStart.clone(); -// calSchedule.add(Calendar.SECOND, (int)tf.getRepetition()); - } + int dayDelta = getDayDelta(now, getNextDayIntForExecution(trigger)); + calSchedule.add(Calendar.DAY_OF_WEEK, dayDelta); Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5); - - return calSchedule; } else Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Trigger " + trigger.toString() + " is not configured to repeat.", 5); - return null; + return calSchedule; } public static boolean areWeInTimeFrame(Trigger trigger, Object triggeringObject)