date time repetition

This commit is contained in:
jens 2024-02-11 17:25:42 +01:00
parent 4bc2781ee7
commit 3dd84220a3
2 changed files with 90 additions and 59 deletions

View File

@ -2,6 +2,7 @@ package com.jens.automation2;
import java.sql.Time; import java.sql.Time;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
public class TimeFrame public class TimeFrame
{ {
@ -20,18 +21,19 @@ public class TimeFrame
public void setDayList(ArrayList<Integer> dayList) public void setDayList(ArrayList<Integer> dayList)
{ {
this.dayList = dayList; this.dayList = dayList;
Collections.sort(dayList);
} }
public void setDayListFromString(String dayListString) public void setDayListFromString(String dayListString)
{ {
// Log.i("Parsing", "Full string: " + dayListString);
char[] dayListCharArray = dayListString.toCharArray(); char[] dayListCharArray = dayListString.toCharArray();
dayList = new ArrayList<Integer>(); dayList = new ArrayList<Integer>();
for(char item : dayListCharArray) for(char item : dayListCharArray)
{ {
// Log.i("Parsing", String.valueOf(item));
dayList.add(Integer.parseInt(String.valueOf(item))); dayList.add(Integer.parseInt(String.valueOf(item)));
} }
Collections.sort(dayList);
} }
public TimeObject getTriggerTimeStart() public TimeObject getTriggerTimeStart()

View File

@ -22,6 +22,7 @@ import com.jens.automation2.Trigger.Trigger_Enum;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.Date; import java.util.Date;
public class DateTimeListener extends BroadcastReceiver implements AutomationListenerInterface 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 @Nullable
@RequiresApi(api = Build.VERSION_CODES.N) @RequiresApi(api = Build.VERSION_CODES.N)
public static Calendar getNextRepeatedExecution(Trigger trigger) 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 now = Calendar.getInstance();
Calendar calculationStart; Calendar calculationStart, calSchedule = null;
TimeObject setTime;
TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2()); TimeFrame tf = new TimeFrame(trigger.getTriggerParameter2());
if(tf.getRepetition() > 0) if(tf.getRepetition() > 0)
@ -383,34 +415,40 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
Are we inside of the timeframe or outside? Are we inside of the timeframe or outside?
Inside -> is this demanded? Inside -> is this demanded?
Yes:
If last execution known, calculate from it If last execution known, calculate from it
If not known, calculate from start of timeframe If not known, calculate from start of timeframe
No: No:
Use end-time and add repetition Use end-time and add repetition
Outisde? -> is this demanded? Outside? -> is this demanded?
Yes:
If last execution known, calculate from it If last execution known, calculate from it
If not known, calculate from end of timeframe If not known, calculate from end of timeframe
No: No:
Use start-time and add repetition 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 = (Calendar) now.clone();
calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours()); calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStart().getHours());
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes()); calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStart().getMinutes());
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds()); calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStart().getSeconds());
calculationStart.set(Calendar.MILLISECOND, 0); calculationStart.set(Calendar.MILLISECOND, 0);
calculationStart.add(Calendar.SECOND, (int) tf.getRepetition()); }
long differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
if(calculationStart.getTimeInMillis() < now.getTimeInMillis() && !areWeInTimeFrame(trigger, new Date())) long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
calculationStart.add(Calendar.DAY_OF_MONTH, 1); calSchedule = (Calendar) calculationStart.clone();
calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));
} }
else else
{ {
@ -419,63 +457,54 @@ public class DateTimeListener extends BroadcastReceiver implements AutomationLis
calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes()); calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes());
calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds()); calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().getSeconds());
calculationStart.set(Calendar.MILLISECOND, 0); calculationStart.set(Calendar.MILLISECOND, 0);
calculationStart.add(Calendar.SECOND, (int) tf.getRepetition()); calSchedule = (Calendar) calculationStart.clone();
calSchedule.add(Calendar.SECOND, (int) tf.getRepetition());
if(calculationStart.getTimeInMillis() < now.getTimeInMillis() && areWeInTimeFrame(trigger, new Date()))
calculationStart.add(Calendar.DAY_OF_MONTH, 1);
}
} }
} }
else else
{ {
if(trigger.getTriggerParameter()) if (!trigger.getTriggerParameter())
{ {
// Miscellaneous.logEvent("i", "DateTimeListener", "Chose start of next interval of trigger in rule " + trigger.getParentRule().getName() + " as calculation start.", 5); if (trigger.getParentRule().getLastExecution() != null)
setTime = tf.getTriggerTimeStart(); {
calculationStart = (Calendar) trigger.getParentRule().getLastExecution().clone();
} }
else 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 = (Calendar) now.clone();
calculationStart.set(Calendar.HOUR_OF_DAY, setTime.getHours()); calculationStart.set(Calendar.HOUR_OF_DAY, tf.getTriggerTimeStop().getHours());
calculationStart.set(Calendar.MINUTE, setTime.getMinutes()); calculationStart.set(Calendar.MINUTE, tf.getTriggerTimeStop().getMinutes());
calculationStart.set(Calendar.SECOND, setTime.getSeconds()); calculationStart.set(Calendar.SECOND, tf.getTriggerTimeStop().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); 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 differenceInSeconds = Math.abs(now.getTimeInMillis() - calculationStart.getTimeInMillis()) / 1000;
long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1; long nextExecutionMultiplier = Math.floorDiv(differenceInSeconds, tf.getRepetition()) + 1;
long nextScheduleTimestamp = (calculationStart.getTimeInMillis() / 1000) + (nextExecutionMultiplier * tf.getRepetition()); calSchedule = (Calendar) calculationStart.clone();
calSchedule = Calendar.getInstance(); calSchedule.add(Calendar.SECOND, (int) (nextExecutionMultiplier * tf.getRepetition()));
calSchedule.setTimeInMillis(nextScheduleTimestamp * 1000);
} }
else 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);
calSchedule = (Calendar) calculationStart.clone(); calSchedule = (Calendar) calculationStart.clone();
// calSchedule.add(Calendar.SECOND, (int)tf.getRepetition()); calSchedule.add(Calendar.SECOND, (int) (tf.getRepetition()));
if()
}
} }
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5); int dayDelta = getDayDelta(now, getNextDayIntForExecution(trigger));
calSchedule.add(Calendar.DAY_OF_WEEK, dayDelta);
return calSchedule; Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Chose " + Miscellaneous.formatDate(calSchedule.getTime()) + " as next repeated execution time.", 5);
} }
else else
Miscellaneous.logEvent("i", "getNextRepeatedExecutionAfter()", "Trigger " + trigger.toString() + " is not configured to repeat.", 5); 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) public static boolean areWeInTimeFrame(Trigger trigger, Object triggeringObject)