[ephemeris] Evolutions of the Ephemeris module (#1169)
* Evolutions of the Ephemeris module Signed-off-by: Gaël L'hopital <gael@lhopital.org>pull/1171/head
parent
2bb19d587f
commit
4fef0100cb
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.core.automation.internal.module.handler;
|
package org.openhab.core.automation.internal.module.handler;
|
||||||
|
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
|
@ -40,7 +41,7 @@ public class EphemerisConditionHandler extends BaseModuleHandler<Condition> impl
|
||||||
|
|
||||||
private final EphemerisManager ephemerisManager;
|
private final EphemerisManager ephemerisManager;
|
||||||
private final @Nullable String dayset;
|
private final @Nullable String dayset;
|
||||||
private final int offset;
|
private final ZonedDateTime target;
|
||||||
|
|
||||||
public EphemerisConditionHandler(Condition condition, EphemerisManager ephemerisManager) {
|
public EphemerisConditionHandler(Condition condition, EphemerisManager ephemerisManager) {
|
||||||
super(condition);
|
super(condition);
|
||||||
|
@ -49,7 +50,8 @@ public class EphemerisConditionHandler extends BaseModuleHandler<Condition> impl
|
||||||
this.dayset = DAYSET_MODULE_TYPE_ID.equals(module.getTypeUID())
|
this.dayset = DAYSET_MODULE_TYPE_ID.equals(module.getTypeUID())
|
||||||
? getValidStringConfigParameter(DAYSET, module.getConfiguration(), module.getId())
|
? getValidStringConfigParameter(DAYSET, module.getConfiguration(), module.getId())
|
||||||
: null;
|
: null;
|
||||||
this.offset = getValidIntegerConfigParameter(OFFSET, module.getConfiguration(), module.getId());
|
int offset = getValidIntegerConfigParameter(OFFSET, module.getConfiguration(), module.getId());
|
||||||
|
target = ZonedDateTime.now().plusDays(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getValidIntegerConfigParameter(String parameter, Configuration config, String moduleId) {
|
private static int getValidIntegerConfigParameter(String parameter, Configuration config, String moduleId) {
|
||||||
|
@ -76,15 +78,15 @@ public class EphemerisConditionHandler extends BaseModuleHandler<Condition> impl
|
||||||
public boolean isSatisfied(Map<String, Object> inputs) {
|
public boolean isSatisfied(Map<String, Object> inputs) {
|
||||||
switch (module.getTypeUID()) {
|
switch (module.getTypeUID()) {
|
||||||
case HOLIDAY_MODULE_TYPE_ID:
|
case HOLIDAY_MODULE_TYPE_ID:
|
||||||
return ephemerisManager.isBankHoliday(offset);
|
return ephemerisManager.isBankHoliday(target);
|
||||||
case WEEKEND_MODULE_TYPE_ID:
|
case WEEKEND_MODULE_TYPE_ID:
|
||||||
return ephemerisManager.isWeekend(offset);
|
return ephemerisManager.isWeekend(target);
|
||||||
case WEEKDAY_MODULE_TYPE_ID:
|
case WEEKDAY_MODULE_TYPE_ID:
|
||||||
return !ephemerisManager.isWeekend(offset);
|
return !ephemerisManager.isWeekend(target);
|
||||||
case DAYSET_MODULE_TYPE_ID:
|
case DAYSET_MODULE_TYPE_ID:
|
||||||
final String dayset = this.dayset;
|
final String dayset = this.dayset;
|
||||||
if (dayset != null) {
|
if (dayset != null) {
|
||||||
return ephemerisManager.isInDayset(dayset, offset);
|
return ephemerisManager.isInDayset(dayset, target);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
package org.eclipse.smarthome.core.ephemeris;
|
package org.eclipse.smarthome.core.ephemeris;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
@ -27,57 +29,145 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||||
public interface EphemerisManager {
|
public interface EphemerisManager {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests given day (related to today) status against configured weekend days
|
* Tests given day status against configured weekend days
|
||||||
*
|
*
|
||||||
* @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday)
|
* @param date observed day
|
||||||
* @return whether the day is on weekend
|
* @return whether the day is on weekend
|
||||||
*/
|
*/
|
||||||
boolean isWeekend(int offset);
|
boolean isWeekend(ZonedDateTime date);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests given day (related to today) status against configured dayset
|
* Tests given day status against configured dayset
|
||||||
*
|
*
|
||||||
* @param daysetName name of the requested dayset, without prefix
|
* @param daysetName name of the requested dayset, without prefix
|
||||||
* @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday)
|
* @param date observed day
|
||||||
* @return whether the day is on weekend
|
* @return whether the day is in the dayset
|
||||||
*/
|
*/
|
||||||
boolean isInDayset(String daysetName, int offset);
|
boolean isInDayset(String daysetName, ZonedDateTime date);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests given day status against official bank holidays
|
* Tests given day status
|
||||||
*
|
*
|
||||||
* @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday)
|
* @param date observed day
|
||||||
* @return whether the day is bank holiday or not
|
* @return whether the day is bank holiday or not
|
||||||
*/
|
*/
|
||||||
boolean isBankHoliday(int offset);
|
boolean isBankHoliday(ZonedDateTime date);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests given day status against given userfile
|
* Tests given day status against given userfile
|
||||||
*
|
*
|
||||||
* @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday)
|
* @param date observed day
|
||||||
* @param filename absolute or relative path to the file on local file system
|
* @param url bundle resource file containing holiday definitions
|
||||||
* @return whether the day is bank holiday or not
|
* @return whether the day is bank holiday or not
|
||||||
* @throws FileNotFoundException if given file does not exist
|
|
||||||
*/
|
*/
|
||||||
boolean isBankHoliday(int offset, String filename) throws FileNotFoundException;
|
boolean isBankHoliday(ZonedDateTime date, URL resource);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get given day bank holiday name
|
* Tests given day status against given userfile
|
||||||
*
|
*
|
||||||
* @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday)
|
* @param date observed day
|
||||||
* @return name of the bank holiday or null if no bank holiday
|
* @param source absolute or relative path to the file on local file system
|
||||||
|
* @return whether the day is bank holiday or not
|
||||||
|
* @throws FileNotFoundException
|
||||||
*/
|
*/
|
||||||
@Nullable
|
boolean isBankHoliday(ZonedDateTime date, String filename) throws FileNotFoundException;
|
||||||
String getBankHolidayName(int offset);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get given day name from given userfile
|
* Get given day name from given userfile
|
||||||
*
|
*
|
||||||
* @param offset Today +/- offset days (+1 = tomorrow, -1 = yesterday)
|
* @param date observed day
|
||||||
* @param filename absolute or relative path to the file on local file system
|
|
||||||
* @return name of the day or null if no corresponding entry
|
* @return name of the day or null if no corresponding entry
|
||||||
* @throws FileNotFoundException if given file does not exist
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
String getBankHolidayName(int offset, String filename) throws FileNotFoundException;
|
String getBankHolidayName(ZonedDateTime date);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get given day name from given userfile
|
||||||
|
*
|
||||||
|
* @param date observed day
|
||||||
|
* @param url bundle resource file containing holiday definitions
|
||||||
|
* @return name of the day or null if no corresponding entry
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getBankHolidayName(ZonedDateTime date, URL resource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get given day name from given userfile
|
||||||
|
*
|
||||||
|
* @param date observed day
|
||||||
|
* @param source absolute or relative path to the file on local file system
|
||||||
|
* @return name of the day or null if no corresponding entry
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getBankHolidayName(ZonedDateTime date, String filename) throws FileNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first next to come holiday in a 1 year time window
|
||||||
|
*
|
||||||
|
* @param startDate first day of the time window
|
||||||
|
* @return next coming holiday
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getNextBankHoliday(ZonedDateTime startDate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first next to come holiday in a 1 year time window
|
||||||
|
*
|
||||||
|
* @param startDate first day of the time window
|
||||||
|
* @param url bundle resource file containing holiday definitions
|
||||||
|
* @return next coming holiday
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getNextBankHoliday(ZonedDateTime startDate, URL resource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the first next to come holiday in a 1 year time window
|
||||||
|
*
|
||||||
|
* @param startDate first day of the time window
|
||||||
|
* @param source absolute or relative path to the file on local file system
|
||||||
|
* @return next coming holiday
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getNextBankHoliday(ZonedDateTime startDate, String filename) throws FileNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the localized holiday description
|
||||||
|
*
|
||||||
|
* @param holidayName code of searched holiday
|
||||||
|
* @return localized holiday description
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String getHolidayDescription(@Nullable String holiday);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of days until searchedHoliday
|
||||||
|
*
|
||||||
|
* @param from first day of the time window
|
||||||
|
* @param searchedHoliday name of the searched holiday
|
||||||
|
* @return difference in days, -1 if not found
|
||||||
|
*/
|
||||||
|
long getDaysUntil(ZonedDateTime from, String searchedHoliday);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of days until searchedHoliday in user file
|
||||||
|
*
|
||||||
|
* @param from first day of the time window
|
||||||
|
* @param searchedHoliday name of the searched holiday
|
||||||
|
* @param url bundle resource file containing holiday definitions
|
||||||
|
* @return difference in days, -1 if not found
|
||||||
|
*/
|
||||||
|
long getDaysUntil(ZonedDateTime from, String searchedHoliday, URL resource);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of days until searchedHoliday in user file
|
||||||
|
*
|
||||||
|
* @param from first day of the time window
|
||||||
|
* @param searchedHoliday name of the searched holiday
|
||||||
|
* @param source absolute or relative path to the file on local file system
|
||||||
|
* @return difference in days, -1 if not found
|
||||||
|
* @throws FileNotFoundException
|
||||||
|
*/
|
||||||
|
long getDaysUntil(ZonedDateTime from, String searchedHoliday, String filename) throws FileNotFoundException;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,9 +24,11 @@ import java.time.DayOfWeek;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.TextStyle;
|
import java.time.format.TextStyle;
|
||||||
|
import java.time.temporal.ChronoUnit;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -35,6 +37,7 @@ import java.util.Map;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||||
import org.eclipse.jdt.annotation.Nullable;
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
|
@ -57,6 +60,7 @@ import de.jollyday.Holiday;
|
||||||
import de.jollyday.HolidayManager;
|
import de.jollyday.HolidayManager;
|
||||||
import de.jollyday.ManagerParameter;
|
import de.jollyday.ManagerParameter;
|
||||||
import de.jollyday.ManagerParameters;
|
import de.jollyday.ManagerParameters;
|
||||||
|
import de.jollyday.util.ResourceUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This service provides functionality around ephemeris services and is the central service to be used directly by
|
* This service provides functionality around ephemeris services and is the central service to be used directly by
|
||||||
|
@ -92,6 +96,10 @@ public class EphemerisManagerImpl implements EphemerisManager, ConfigOptionProvi
|
||||||
final Map<String, Set<DayOfWeek>> daysets = new HashMap<>();
|
final Map<String, Set<DayOfWeek>> daysets = new HashMap<>();
|
||||||
private final Map<Object, HolidayManager> holidayManagers = new HashMap<>();
|
private final Map<Object, HolidayManager> holidayManagers = new HashMap<>();
|
||||||
private final List<String> countryParameters = new ArrayList<>();
|
private final List<String> countryParameters = new ArrayList<>();
|
||||||
|
/**
|
||||||
|
* Utility for accessing resources.
|
||||||
|
*/
|
||||||
|
private final ResourceUtil resourceUtil = new ResourceUtil();
|
||||||
|
|
||||||
private final LocaleProvider localeProvider;
|
private final LocaleProvider localeProvider;
|
||||||
|
|
||||||
|
@ -198,6 +206,18 @@ public class EphemerisManagerImpl implements EphemerisManager, ConfigOptionProvi
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private URL getUrl(String filename) throws FileNotFoundException {
|
||||||
|
if (Files.exists(Paths.get(filename))) {
|
||||||
|
try {
|
||||||
|
return new URL("file:" + filename);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
throw new FileNotFoundException(e.getMessage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new FileNotFoundException(filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private HolidayManager getHolidayManager(Object managerKey) {
|
private HolidayManager getHolidayManager(Object managerKey) {
|
||||||
return holidayManagers.computeIfAbsent(managerKey, key -> {
|
return holidayManagers.computeIfAbsent(managerKey, key -> {
|
||||||
final ManagerParameter parameters = managerKey.getClass() == String.class
|
final ManagerParameter parameters = managerKey.getClass() == String.class
|
||||||
|
@ -207,45 +227,64 @@ public class EphemerisManagerImpl implements EphemerisManager, ConfigOptionProvi
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<Holiday> getHoliday(ZonedDateTime date) {
|
private List<Holiday> getHolidays(ZonedDateTime from, int span, HolidayManager holidayManager) {
|
||||||
HolidayManager manager = getHolidayManager(country);
|
LocalDate fromDate = from.toLocalDate();
|
||||||
LocalDate localDate = date.toLocalDate();
|
LocalDate toDate = from.plusDays(span).toLocalDate();
|
||||||
|
|
||||||
Set<Holiday> holidays = manager.getHolidays(localDate, localDate, countryParameters.toArray(new String[0]));
|
Set<Holiday> days = holidayManager.getHolidays(fromDate, toDate, countryParameters.toArray(new String[0]));
|
||||||
return holidays.isEmpty() ? Optional.empty() : Optional.of(holidays.iterator().next());
|
List<Holiday> sortedHolidays = days.stream().sorted(Comparator.comparing(Holiday::getDate))
|
||||||
}
|
.collect(Collectors.toList());
|
||||||
|
return sortedHolidays;
|
||||||
private boolean isBankHoliday(ZonedDateTime date) {
|
|
||||||
Optional<Holiday> holiday = getHoliday(date);
|
|
||||||
return holiday.isPresent();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBankHoliday(int offset) {
|
public long getDaysUntil(ZonedDateTime from, String searchedHoliday) {
|
||||||
return isBankHoliday(ZonedDateTime.now().plusDays(offset));
|
List<Holiday> sortedHolidays = getHolidays(from, 366, getHolidayManager(country));
|
||||||
|
Optional<Holiday> result = sortedHolidays.stream()
|
||||||
|
.filter(holiday -> searchedHoliday.equalsIgnoreCase(holiday.getPropertiesKey())).findFirst();
|
||||||
|
return result.isPresent() ? from.toLocalDate().until(result.get().getDate(), ChronoUnit.DAYS) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isBankHoliday(int offset, String filename) throws FileNotFoundException {
|
public long getDaysUntil(ZonedDateTime from, String searchedHoliday, URL resource) {
|
||||||
Optional<String> holiday = getHolidayUserFile(ZonedDateTime.now().plusDays(offset), filename);
|
List<Holiday> sortedHolidays = getHolidays(from, 366, getHolidayManager(resource));
|
||||||
return holiday.isPresent();
|
Optional<Holiday> result = sortedHolidays.stream()
|
||||||
|
.filter(holiday -> searchedHoliday.equalsIgnoreCase(holiday.getPropertiesKey())).findFirst();
|
||||||
|
return result.isPresent() ? from.toLocalDate().until(result.get().getDate(), ChronoUnit.DAYS) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isWeekend(int offset) {
|
public long getDaysUntil(ZonedDateTime from, String searchedHoliday, String filename) throws FileNotFoundException {
|
||||||
return isWeekend(ZonedDateTime.now().plusDays(offset));
|
return getDaysUntil(from, searchedHoliday, getUrl(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWeekend(ZonedDateTime date) {
|
private @Nullable String getFirstBankHolidayKey(ZonedDateTime from, int span, HolidayManager holidayManager) {
|
||||||
|
Optional<Holiday> holiday = getHolidays(from, span, holidayManager).stream().findFirst();
|
||||||
|
return holiday.map(p -> p.getPropertiesKey()).orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBankHoliday(ZonedDateTime date) {
|
||||||
|
return !getHolidays(date, 0, getHolidayManager(country)).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBankHoliday(ZonedDateTime date, URL resource) {
|
||||||
|
return !getHolidays(date, 0, getHolidayManager(resource)).isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBankHoliday(ZonedDateTime date, String filename) throws FileNotFoundException {
|
||||||
|
return isBankHoliday(date, getUrl(filename));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWeekend(ZonedDateTime date) {
|
||||||
return isInDayset(CONFIG_DAYSET_WEEKEND, date);
|
return isInDayset(CONFIG_DAYSET_WEEKEND, date);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInDayset(String daysetName, int offset) {
|
public boolean isInDayset(String daysetName, ZonedDateTime date) {
|
||||||
return isInDayset(daysetName, ZonedDateTime.now().plusDays(offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isInDayset(String daysetName, ZonedDateTime date) {
|
|
||||||
if (daysets.containsKey(daysetName)) {
|
if (daysets.containsKey(daysetName)) {
|
||||||
DayOfWeek dow = date.getDayOfWeek();
|
DayOfWeek dow = date.getDayOfWeek();
|
||||||
return daysets.get(daysetName).contains(dow);
|
return daysets.get(daysetName).contains(dow);
|
||||||
|
@ -255,34 +294,34 @@ public class EphemerisManagerImpl implements EphemerisManager, ConfigOptionProvi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getBankHolidayName(ZonedDateTime date) {
|
@Override
|
||||||
Optional<Holiday> holiday = getHoliday(date);
|
public @Nullable String getBankHolidayName(ZonedDateTime date) {
|
||||||
return holiday.map(p -> p.getDescription(localeProvider.getLocale())).orElse(null);
|
return getFirstBankHolidayKey(date, 0, getHolidayManager(country));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable String getBankHolidayName(int offset) {
|
public @Nullable String getBankHolidayName(ZonedDateTime date, URL resource) {
|
||||||
return getBankHolidayName(ZonedDateTime.now().plusDays(offset));
|
return getFirstBankHolidayKey(date, 0, getHolidayManager(resource));
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<String> getHolidayUserFile(ZonedDateTime date, String filename) throws FileNotFoundException {
|
|
||||||
if (Files.exists(Paths.get(filename))) {
|
|
||||||
try {
|
|
||||||
URL url = new URL("file:" + filename);
|
|
||||||
Set<Holiday> days = getHolidayManager(url).getHolidays(date.toLocalDate(), date.toLocalDate());
|
|
||||||
return days.isEmpty() ? Optional.empty() : Optional.of(days.iterator().next().getPropertiesKey());
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
throw new FileNotFoundException(e.getMessage());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new FileNotFoundException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public @Nullable String getBankHolidayName(int offset, String filename) throws FileNotFoundException {
|
public @Nullable String getBankHolidayName(ZonedDateTime date, String filename) throws FileNotFoundException {
|
||||||
Optional<String> holiday = getHolidayUserFile(ZonedDateTime.now().plusDays(offset), filename);
|
return getBankHolidayName(date, getUrl(filename));
|
||||||
return holiday.isPresent() ? holiday.get() : null;
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getNextBankHoliday(ZonedDateTime from) {
|
||||||
|
return getFirstBankHolidayKey(from, 365, getHolidayManager(country));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getNextBankHoliday(ZonedDateTime from, URL resource) {
|
||||||
|
return getFirstBankHolidayKey(from, 365, getHolidayManager(resource));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getNextBankHoliday(ZonedDateTime from, String filename) throws FileNotFoundException {
|
||||||
|
return getNextBankHoliday(from, getUrl(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDayset(String setName, Iterable<?> values) {
|
private void addDayset(String setName, Iterable<?> values) {
|
||||||
|
@ -359,4 +398,10 @@ public class EphemerisManagerImpl implements EphemerisManager, ConfigOptionProvi
|
||||||
throw new IllegalArgumentException("Unable to parse property - token is empty.");
|
throw new IllegalArgumentException("Unable to parse property - token is empty.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable String getHolidayDescription(@Nullable String holiday) {
|
||||||
|
return holiday != null ? resourceUtil.getHolidayDescription(localeProvider.getLocale(), holiday) : null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,9 @@
|
||||||
package org.eclipse.smarthome.model.script.actions;
|
package org.eclipse.smarthome.model.script.actions;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
|
|
||||||
|
import org.eclipse.jdt.annotation.Nullable;
|
||||||
import org.eclipse.smarthome.model.script.engine.action.ActionDoc;
|
import org.eclipse.smarthome.model.script.engine.action.ActionDoc;
|
||||||
import org.eclipse.smarthome.model.script.internal.engine.action.EphemerisActionService;
|
import org.eclipse.smarthome.model.script.internal.engine.action.EphemerisActionService;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -35,7 +37,12 @@ public class Ephemeris {
|
||||||
|
|
||||||
@ActionDoc(text = "checks if today plus or minus a given offset is a weekend day")
|
@ActionDoc(text = "checks if today plus or minus a given offset is a weekend day")
|
||||||
public static boolean isWeekend(int offset) {
|
public static boolean isWeekend(int offset) {
|
||||||
return EphemerisActionService.ephemerisManager.isWeekend(offset);
|
return isWeekend(ZonedDateTime.now().plusDays(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "checks if a given day is a weekend day")
|
||||||
|
public static boolean isWeekend(ZonedDateTime day) {
|
||||||
|
return EphemerisActionService.ephemerisManager.isWeekend(day);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "checks if today is defined in a given dayset")
|
@ActionDoc(text = "checks if today is defined in a given dayset")
|
||||||
|
@ -45,7 +52,12 @@ public class Ephemeris {
|
||||||
|
|
||||||
@ActionDoc(text = "checks if today plus or minus a given offset is defined in a given dayset")
|
@ActionDoc(text = "checks if today plus or minus a given offset is defined in a given dayset")
|
||||||
public static boolean isInDayset(String daysetName, int offset) {
|
public static boolean isInDayset(String daysetName, int offset) {
|
||||||
return EphemerisActionService.ephemerisManager.isInDayset(daysetName, offset);
|
return isInDayset(daysetName, ZonedDateTime.now().plusDays(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "checks a given day is defined in a given dayset")
|
||||||
|
public static boolean isInDayset(String daysetName, ZonedDateTime day) {
|
||||||
|
return EphemerisActionService.ephemerisManager.isInDayset(daysetName, day);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "checks if today is bank holiday")
|
@ActionDoc(text = "checks if today is bank holiday")
|
||||||
|
@ -55,13 +67,23 @@ public class Ephemeris {
|
||||||
|
|
||||||
@ActionDoc(text = "checks if today plus or minus a given offset is bank holiday")
|
@ActionDoc(text = "checks if today plus or minus a given offset is bank holiday")
|
||||||
public static boolean isBankHoliday(int offset) {
|
public static boolean isBankHoliday(int offset) {
|
||||||
return EphemerisActionService.ephemerisManager.isBankHoliday(offset);
|
return isBankHoliday(ZonedDateTime.now().plusDays(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "checks a given day is bank holiday")
|
||||||
|
public static boolean isBankHoliday(ZonedDateTime day) {
|
||||||
|
return EphemerisActionService.ephemerisManager.isBankHoliday(day);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "checks if today plus or minus a given offset is bank holiday from a given userfile")
|
@ActionDoc(text = "checks if today plus or minus a given offset is bank holiday from a given userfile")
|
||||||
public static boolean isBankHoliday(int offset, String filename) {
|
public static boolean isBankHoliday(int offset, String filename) {
|
||||||
|
return isBankHoliday(ZonedDateTime.now().plusDays(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "checks a given day is bank holiday from a given userfile")
|
||||||
|
public static boolean isBankHoliday(ZonedDateTime day, String filename) {
|
||||||
try {
|
try {
|
||||||
return EphemerisActionService.ephemerisManager.isBankHoliday(offset, filename);
|
return EphemerisActionService.ephemerisManager.isBankHoliday(day, filename);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage());
|
LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage());
|
||||||
return false;
|
return false;
|
||||||
|
@ -69,28 +91,103 @@ public class Ephemeris {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "get todays bank holiday name")
|
@ActionDoc(text = "get todays bank holiday name")
|
||||||
public static String getBankHolidayName() {
|
public static @Nullable String getBankHolidayName() {
|
||||||
return getBankHolidayName(0);
|
return getBankHolidayName(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "get bank holiday name for today plus or minus a given offset")
|
@ActionDoc(text = "get bank holiday name for today plus or minus a given offset")
|
||||||
public static String getBankHolidayName(int offset) {
|
public static @Nullable String getBankHolidayName(int offset) {
|
||||||
return EphemerisActionService.ephemerisManager.getBankHolidayName(offset);
|
return getBankHolidayName(ZonedDateTime.now().plusDays(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "get bank holiday name for a given day")
|
||||||
|
public static @Nullable String getBankHolidayName(ZonedDateTime day) {
|
||||||
|
return EphemerisActionService.ephemerisManager.getBankHolidayName(day);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "get holiday for today from a given userfile")
|
@ActionDoc(text = "get holiday for today from a given userfile")
|
||||||
public static String getBankHolidayName(String filename) {
|
public static @Nullable String getBankHolidayName(String filename) {
|
||||||
return getBankHolidayName(0, filename);
|
return getBankHolidayName(0, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ActionDoc(text = "get holiday for today plus or minus an offset from a given userfile")
|
@ActionDoc(text = "get holiday for today plus or minus an offset from a given userfile")
|
||||||
public static String getBankHolidayName(int offset, String filename) {
|
public static @Nullable String getBankHolidayName(int offset, String filename) {
|
||||||
|
return getBankHolidayName(ZonedDateTime.now().plusDays(offset), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "get holiday for a given day from a given userfile")
|
||||||
|
public static @Nullable String getBankHolidayName(ZonedDateTime day, String filename) {
|
||||||
try {
|
try {
|
||||||
return EphemerisActionService.ephemerisManager.getBankHolidayName(offset, filename);
|
return EphemerisActionService.ephemerisManager.getBankHolidayName(day, filename);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage());
|
LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@ActionDoc(text = "get next bank holiday")
|
||||||
|
public static @Nullable String getNextBankHoliday() {
|
||||||
|
return getNextBankHoliday(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "get next bank holiday plus or minus an offset")
|
||||||
|
public static @Nullable String getNextBankHoliday(int offset) {
|
||||||
|
return getNextBankHoliday(ZonedDateTime.now().plusDays(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "get next bank holiday holiday from a given day")
|
||||||
|
public static @Nullable String getNextBankHoliday(ZonedDateTime day) {
|
||||||
|
return EphemerisActionService.ephemerisManager.getNextBankHoliday(day);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "get next bank holiday from a given userfile")
|
||||||
|
public static @Nullable String getNextBankHoliday(String filename) {
|
||||||
|
return getNextBankHoliday(0, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "get next bank holiday plus or minus an offset from a given userfile")
|
||||||
|
public static @Nullable String getNextBankHoliday(int offset, String filename) {
|
||||||
|
return getNextBankHoliday(ZonedDateTime.now().plusDays(offset), filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "get next bank holiday a given day from a given userfilee")
|
||||||
|
public static @Nullable String getNextBankHoliday(ZonedDateTime day, String filename) {
|
||||||
|
try {
|
||||||
|
return EphemerisActionService.ephemerisManager.getNextBankHoliday(day, filename);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "gets the localized description of a holiday key name")
|
||||||
|
public static @Nullable String getHolidayDescription(@Nullable String holiday) {
|
||||||
|
return EphemerisActionService.ephemerisManager.getHolidayDescription(holiday);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "gets the number of days between today and a given holiday")
|
||||||
|
public static long getDaysUntil(String searchedHoliday) {
|
||||||
|
return getDaysUntil(ZonedDateTime.now(), searchedHoliday);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "gets the number of days between today and a given holiday")
|
||||||
|
public static long getDaysUntil(ZonedDateTime day, String searchedHoliday) {
|
||||||
|
return EphemerisActionService.ephemerisManager.getDaysUntil(day, searchedHoliday);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "gets the number of days between today and a given holiday from a given userfile")
|
||||||
|
public static long getDaysUntil(String searchedHoliday, String filename) {
|
||||||
|
return getDaysUntil(ZonedDateTime.now(), searchedHoliday, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ActionDoc(text = "gets the number of days between a given day and a given holiday from a given userfile")
|
||||||
|
public static long getDaysUntil(ZonedDateTime day, String searchedHoliday, String filename) {
|
||||||
|
try {
|
||||||
|
return EphemerisActionService.ephemerisManager.getDaysUntil(day, searchedHoliday, filename);
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
LOGGER.error("Error reading holiday user file {} : {}", filename, e.getMessage());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -16,7 +16,10 @@ import static org.eclipse.smarthome.core.ephemeris.internal.EphemerisManagerImpl
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.net.URL;
|
||||||
import java.time.DayOfWeek;
|
import java.time.DayOfWeek;
|
||||||
|
import java.time.ZoneId;
|
||||||
|
import java.time.ZonedDateTime;
|
||||||
import java.util.AbstractMap.SimpleEntry;
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -41,7 +44,7 @@ import org.junit.Test;
|
||||||
*/
|
*/
|
||||||
@NonNullByDefault
|
@NonNullByDefault
|
||||||
public class EphemerisManagerImplOSGiTest extends JavaOSGiTest {
|
public class EphemerisManagerImplOSGiTest extends JavaOSGiTest {
|
||||||
|
private static final String INTERNAL_DAYSET = "internal";
|
||||||
private static final URI CONFIG_URI = URI.create("system:ephemeris");
|
private static final URI CONFIG_URI = URI.create("system:ephemeris");
|
||||||
private static final String COUNTRY_AUSTRALIA_KEY = "au";
|
private static final String COUNTRY_AUSTRALIA_KEY = "au";
|
||||||
private static final String COUNTRY_AUSTRALIA_NAME = "Australia";
|
private static final String COUNTRY_AUSTRALIA_NAME = "Australia";
|
||||||
|
@ -233,4 +236,81 @@ public class EphemerisManagerImplOSGiTest extends JavaOSGiTest {
|
||||||
assertFalse(options.isEmpty());
|
assertFalse(options.isEmpty());
|
||||||
assertEquals(ephemerisManager.cities.get(REGION_TASMANIA_KEY), options);
|
assertEquals(ephemerisManager.cities.get(REGION_TASMANIA_KEY), options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWeekends() {
|
||||||
|
ZonedDateTime monday = ZonedDateTime.of(2019, 10, 28, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
ZonedDateTime sunday = ZonedDateTime.of(2019, 10, 27, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
ephemerisManager.modified(Collections.singletonMap(CONFIG_DAYSET_PREFIX + INTERNAL_DAYSET,
|
||||||
|
Stream.of("Monday", "Tuesday").collect(Collectors.toList())));
|
||||||
|
assertEquals(true, ephemerisManager.isWeekend(sunday));
|
||||||
|
assertEquals(false, ephemerisManager.isWeekend(monday));
|
||||||
|
assertEquals(true, ephemerisManager.isInDayset(INTERNAL_DAYSET, monday));
|
||||||
|
assertEquals(false, ephemerisManager.isInDayset(INTERNAL_DAYSET, sunday));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIsBankHoliday() {
|
||||||
|
ZonedDateTime newyearsday = ZonedDateTime.of(2019, 01, 01, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
ZonedDateTime secondday = ZonedDateTime.of(2019, 01, 02, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
|
||||||
|
boolean vacation = ephemerisManager.isBankHoliday(newyearsday);
|
||||||
|
assertEquals(true, vacation);
|
||||||
|
|
||||||
|
vacation = ephemerisManager.isBankHoliday(secondday);
|
||||||
|
assertEquals(false, vacation);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetBankHoliday() {
|
||||||
|
ZonedDateTime theDay = ZonedDateTime.of(2019, 01, 01, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
|
||||||
|
boolean vacation = ephemerisManager.isBankHoliday(theDay);
|
||||||
|
assertEquals(true, vacation);
|
||||||
|
|
||||||
|
String code = ephemerisManager.getBankHolidayName(theDay);
|
||||||
|
assertEquals("NEW_YEAR", code);
|
||||||
|
|
||||||
|
String name = ephemerisManager.getHolidayDescription(code);
|
||||||
|
assertNotNull(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNextBankHoliday() {
|
||||||
|
ZonedDateTime today = ZonedDateTime.of(2019, 12, 28, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
long delay = ephemerisManager.getDaysUntil(today, "NONEXISTING");
|
||||||
|
assertEquals(-1, delay);
|
||||||
|
|
||||||
|
String next = ephemerisManager.getNextBankHoliday(today);
|
||||||
|
assertEquals("NEW_YEAR", next);
|
||||||
|
if (next != null) {
|
||||||
|
String description = ephemerisManager.getHolidayDescription(next);
|
||||||
|
assertNotNull(description);
|
||||||
|
|
||||||
|
delay = ephemerisManager.getDaysUntil(today, next);
|
||||||
|
assertEquals(4, delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserFile() {
|
||||||
|
URL url = bundleContext.getBundle().getResource("events.xml");
|
||||||
|
|
||||||
|
ZonedDateTime today = ZonedDateTime.of(2019, 10, 28, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
ZonedDateTime theDay = ZonedDateTime.of(2019, 10, 31, 0, 0, 0, 0, ZoneId.of("Europe/Paris"));
|
||||||
|
|
||||||
|
boolean vacation = ephemerisManager.isBankHoliday(theDay, url);
|
||||||
|
assertEquals(true, vacation);
|
||||||
|
|
||||||
|
long delay = ephemerisManager.getDaysUntil(today, "Halloween", url);
|
||||||
|
assertEquals(3, delay);
|
||||||
|
|
||||||
|
String next = ephemerisManager.getNextBankHoliday(today, url);
|
||||||
|
assertEquals("Halloween", next);
|
||||||
|
|
||||||
|
String result = ephemerisManager.getBankHolidayName(theDay, url);
|
||||||
|
assertEquals("Halloween", result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<tns:Configuration hierarchy="fr" description="France"
|
||||||
|
xmlns:tns="http://www.example.org/Holiday" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.example.org/Holiday /Holiday.xsd">
|
||||||
|
<tns:Holidays>
|
||||||
|
<tns:Fixed month="DECEMBER" day="29" descriptionPropertiesKey="Innocents" />
|
||||||
|
<tns:FixedWeekday which="THIRD" weekday="SUNDAY" month="JUNE" descriptionPropertiesKey="Fête des pères"/>
|
||||||
|
<tns:FixedWeekday which="FIRST" weekday="SUNDAY" month="MARCH" descriptionPropertiesKey="Fête des grands-mères"/>
|
||||||
|
<tns:FixedWeekday which="FIRST" weekday="SUNDAY" month="OCTOBER" descriptionPropertiesKey="Fête des grands-pères"/>
|
||||||
|
<tns:FixedWeekday which="LAST" weekday="SUNDAY" month="MAY" descriptionPropertiesKey="Fête des mères"/>
|
||||||
|
<tns:FixedWeekday which="LAST" weekday="SUNDAY" month="MARCH" descriptionPropertiesKey="Passage heure d'été"/>
|
||||||
|
<tns:FixedWeekday which="LAST" weekday="SUNDAY" month="OCTOBER" descriptionPropertiesKey="Passage heure d'hiver"/>
|
||||||
|
<tns:FixedWeekday which="THIRD" weekday="THURSDAY" month="NOVEMBER" descriptionPropertiesKey="Beaujolais Nouveau"/>
|
||||||
|
<tns:Fixed month="JUNE" day="21" descriptionPropertiesKey="Fête de la musique"/>
|
||||||
|
<tns:Fixed month="APRIL" day="1" descriptionPropertiesKey="Poisson d'avril"/>
|
||||||
|
<tns:Fixed month="MAY" day="1" descriptionPropertiesKey="Fête du muguet"/>
|
||||||
|
<tns:Fixed month="OCTOBER" day="31" descriptionPropertiesKey="Halloween"/>
|
||||||
|
<tns:Fixed month="FEBRUARY" day="2" descriptionPropertiesKey="Chandeleur"/>
|
||||||
|
</tns:Holidays>
|
||||||
|
</tns:Configuration>
|
Loading…
Reference in New Issue