mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[astro] Various refactoring/fixes (#19310)
* Fix DateTimeUtilsTest default Locale dependency Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
This commit is contained in:
+6
-19
@@ -14,8 +14,6 @@ package org.openhab.binding.astro.internal;
|
||||
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@@ -23,6 +21,7 @@ import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
import org.openhab.binding.astro.internal.handler.MoonHandler;
|
||||
import org.openhab.binding.astro.internal.handler.SunHandler;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@@ -44,15 +43,16 @@ import org.osgi.service.component.annotations.Reference;
|
||||
public class AstroHandlerFactory extends BaseThingHandlerFactory {
|
||||
|
||||
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_SUN, THING_TYPE_MOON);
|
||||
private static final Map<String, AstroThingHandler> ASTRO_THING_HANDLERS = new HashMap<>();
|
||||
private final CronScheduler scheduler;
|
||||
private final TimeZoneProvider timeZoneProvider;
|
||||
private final LocaleProvider localeProvider;
|
||||
|
||||
@Activate
|
||||
public AstroHandlerFactory(final @Reference CronScheduler scheduler,
|
||||
final @Reference TimeZoneProvider timeZoneProvider) {
|
||||
final @Reference TimeZoneProvider timeZoneProvider, @Reference LocaleProvider localeProvider) {
|
||||
this.scheduler = scheduler;
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.localeProvider = localeProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,23 +65,10 @@ public class AstroHandlerFactory extends BaseThingHandlerFactory {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
AstroThingHandler thingHandler = null;
|
||||
if (thingTypeUID.equals(THING_TYPE_SUN)) {
|
||||
thingHandler = new SunHandler(thing, scheduler, timeZoneProvider);
|
||||
thingHandler = new SunHandler(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
} else if (thingTypeUID.equals(THING_TYPE_MOON)) {
|
||||
thingHandler = new MoonHandler(thing, scheduler, timeZoneProvider);
|
||||
}
|
||||
if (thingHandler != null) {
|
||||
ASTRO_THING_HANDLERS.put(thing.getUID().toString(), thingHandler);
|
||||
thingHandler = new MoonHandler(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
}
|
||||
return thingHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unregisterHandler(Thing thing) {
|
||||
super.unregisterHandler(thing);
|
||||
ASTRO_THING_HANDLERS.remove(thing.getUID().toString());
|
||||
}
|
||||
|
||||
public static @Nullable AstroThingHandler getHandler(String thingUid) {
|
||||
return ASTRO_THING_HANDLERS.get(thingUid);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -99,7 +99,7 @@ public class AstroActions implements ThingActions {
|
||||
if (theHandler != null) {
|
||||
if (theHandler instanceof SunHandler sunHandler) {
|
||||
Radiation radiation = sunHandler.getRadiationAt(date != null ? date : ZonedDateTime.now());
|
||||
return radiation.getTotal();
|
||||
return radiation == null ? null : radiation.getTotal();
|
||||
} else {
|
||||
logger.info("Astro Action service ThingHandler is not a SunHandler!");
|
||||
}
|
||||
|
||||
+32
-14
@@ -15,7 +15,10 @@ package org.openhab.binding.astro.internal.calc;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.model.Eclipse;
|
||||
import org.openhab.binding.astro.internal.model.EclipseKind;
|
||||
import org.openhab.binding.astro.internal.model.EclipseType;
|
||||
@@ -39,6 +42,7 @@ import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
* http://www.computus.de/mondphase/mondphase.htm azimuth/elevation and
|
||||
* zodiac based on http://lexikon.astronomie.info/java/sunmoon/
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MoonCalc {
|
||||
private static final double NEW_MOON = 0;
|
||||
private static final double FULL_MOON = 0.5;
|
||||
@@ -48,7 +52,7 @@ public class MoonCalc {
|
||||
/**
|
||||
* Calculates all moon data at the specified coordinates
|
||||
*/
|
||||
public Moon getMoonInfo(Calendar calendar, double latitude, double longitude) {
|
||||
public Moon getMoonInfo(Calendar calendar, double latitude, double longitude, TimeZone zone, Locale locale) {
|
||||
Moon moon = new Moon();
|
||||
|
||||
double julianDate = DateTimeUtils.dateToJulianDate(calendar);
|
||||
@@ -75,26 +79,31 @@ public class MoonCalc {
|
||||
moon.setSet(new Range(set, set));
|
||||
|
||||
MoonPhase phase = moon.getPhase();
|
||||
phase.setNew(DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, NEW_MOON)));
|
||||
phase.setFirstQuarter(DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, FIRST_QUARTER)));
|
||||
phase.setFull(DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, FULL_MOON)));
|
||||
phase.setThirdQuarter(DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, LAST_QUARTER)));
|
||||
phase.setNew(DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, NEW_MOON), zone, locale));
|
||||
phase.setFirstQuarter(
|
||||
DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, FIRST_QUARTER), zone, locale));
|
||||
phase.setFull(DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, FULL_MOON), zone, locale));
|
||||
phase.setThirdQuarter(
|
||||
DateTimeUtils.toCalendar(getNextPhase(calendar, julianDateMidnight, LAST_QUARTER), zone, locale));
|
||||
|
||||
Eclipse eclipse = moon.getEclipse();
|
||||
eclipse.getKinds().forEach(eclipseKind -> {
|
||||
double jdate = getEclipse(calendar, EclipseType.MOON, julianDateMidnight, eclipseKind);
|
||||
eclipse.set(eclipseKind, DateTimeUtils.toCalendar(jdate), new Position());
|
||||
Calendar eclipseDate = DateTimeUtils.toCalendar(jdate, zone, locale);
|
||||
if (eclipseDate != null) {
|
||||
eclipse.set(eclipseKind, eclipseDate, new Position());
|
||||
}
|
||||
});
|
||||
|
||||
double decimalYear = DateTimeUtils.getDecimalYear(calendar);
|
||||
MoonDistance apogee = moon.getApogee();
|
||||
double apogeeJd = getApogee(julianDate, decimalYear);
|
||||
apogee.setDate(DateTimeUtils.toCalendar(apogeeJd));
|
||||
apogee.setDate(DateTimeUtils.toCalendar(apogeeJd, zone, locale));
|
||||
apogee.setDistance(getDistance(apogeeJd));
|
||||
|
||||
MoonDistance perigee = moon.getPerigee();
|
||||
double perigeeJd = getPerigee(julianDate, decimalYear);
|
||||
perigee.setDate(DateTimeUtils.toCalendar(perigeeJd));
|
||||
perigee.setDate(DateTimeUtils.toCalendar(perigeeJd, zone, locale));
|
||||
perigee.setDistance(getDistance(perigeeJd));
|
||||
|
||||
return moon;
|
||||
@@ -103,28 +112,37 @@ public class MoonCalc {
|
||||
/**
|
||||
* Calculates the moon illumination and distance.
|
||||
*/
|
||||
public void setPositionalInfo(Calendar calendar, double latitude, double longitude, Moon moon) {
|
||||
public void setPositionalInfo(Calendar calendar, double latitude, double longitude, Moon moon, TimeZone zone,
|
||||
Locale locale) {
|
||||
double julianDate = DateTimeUtils.dateToJulianDate(calendar);
|
||||
setMoonPhase(calendar, moon);
|
||||
setMoonPhase(calendar, moon, zone, locale);
|
||||
setAzimuthElevationZodiac(julianDate, latitude, longitude, moon);
|
||||
|
||||
MoonDistance distance = moon.getDistance();
|
||||
distance.setDate(Calendar.getInstance());
|
||||
distance.setDate(calendar);
|
||||
distance.setDistance(getDistance(julianDate));
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the age and the current phase.
|
||||
*/
|
||||
private void setMoonPhase(Calendar calendar, Moon moon) {
|
||||
private void setMoonPhase(Calendar calendar, Moon moon, TimeZone zone, Locale locale) {
|
||||
MoonPhase phase = moon.getPhase();
|
||||
double julianDate = DateTimeUtils.dateToJulianDate(calendar);
|
||||
double parentNewMoon = getPreviousPhase(calendar, julianDate, NEW_MOON);
|
||||
double age = Math.abs(parentNewMoon - julianDate);
|
||||
Calendar parentNewMoonCal = DateTimeUtils.toCalendar(parentNewMoon, zone, locale);
|
||||
if (parentNewMoonCal == null) {
|
||||
return;
|
||||
}
|
||||
phase.setAge(age);
|
||||
|
||||
long parentNewMoonMillis = DateTimeUtils.toCalendar(parentNewMoon).getTimeInMillis();
|
||||
long ageRangeTimeMillis = phase.getNew().getTimeInMillis() - parentNewMoonMillis;
|
||||
long parentNewMoonMillis = parentNewMoonCal.getTimeInMillis();
|
||||
Calendar cal = phase.getNew();
|
||||
if (cal == null) {
|
||||
return;
|
||||
}
|
||||
long ageRangeTimeMillis = cal.getTimeInMillis() - parentNewMoonMillis;
|
||||
long ageCurrentMillis = System.currentTimeMillis() - parentNewMoonMillis;
|
||||
double agePercent = ageRangeTimeMillis != 0 ? ageCurrentMillis * 100.0 / ageRangeTimeMillis : 0;
|
||||
phase.setAgePercent(agePercent);
|
||||
|
||||
+76
-36
@@ -13,7 +13,11 @@
|
||||
package org.openhab.binding.astro.internal.calc;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.model.Season;
|
||||
import org.openhab.binding.astro.internal.model.SeasonName;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
@@ -24,44 +28,61 @@ import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
* @implNote based on the calculations of http://stellafane.org/misc/equinox.html
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SeasonCalc {
|
||||
private int currentYear;
|
||||
private Season currentSeason;
|
||||
private @Nullable Season currentSeason;
|
||||
|
||||
/**
|
||||
* Returns the seasons of the year of the specified calendar.
|
||||
*/
|
||||
public Season getSeason(Calendar calendar, double latitude, boolean useMeteorologicalSeason) {
|
||||
public Season getSeason(Calendar calendar, double latitude, boolean useMeteorologicalSeason, TimeZone zone,
|
||||
Locale locale) {
|
||||
int year = calendar.get(Calendar.YEAR);
|
||||
boolean isSouthernHemisphere = latitude < 0.0;
|
||||
Season season = currentSeason;
|
||||
if (currentYear != year) {
|
||||
season = new Season();
|
||||
if (!isSouthernHemisphere) {
|
||||
season.setSpring(calcEquiSol(0, year));
|
||||
season.setSummer(calcEquiSol(1, year));
|
||||
season.setAutumn(calcEquiSol(2, year));
|
||||
season.setWinter(calcEquiSol(3, year));
|
||||
season.setSpring(calcEquiSol(0, year, zone, locale));
|
||||
season.setSummer(calcEquiSol(1, year, zone, locale));
|
||||
season.setAutumn(calcEquiSol(2, year, zone, locale));
|
||||
season.setWinter(calcEquiSol(3, year, zone, locale));
|
||||
} else {
|
||||
season.setSpring(calcEquiSol(2, year));
|
||||
season.setSummer(calcEquiSol(3, year));
|
||||
season.setAutumn(calcEquiSol(0, year));
|
||||
season.setWinter(calcEquiSol(1, year));
|
||||
season.setSpring(calcEquiSol(2, year, zone, locale));
|
||||
season.setSummer(calcEquiSol(3, year, zone, locale));
|
||||
season.setAutumn(calcEquiSol(0, year, zone, locale));
|
||||
season.setWinter(calcEquiSol(1, year, zone, locale));
|
||||
}
|
||||
currentSeason = season;
|
||||
currentYear = year;
|
||||
}
|
||||
|
||||
if (useMeteorologicalSeason) {
|
||||
atMidnightOfFirstMonthDay(season.getSpring());
|
||||
atMidnightOfFirstMonthDay(season.getSummer());
|
||||
atMidnightOfFirstMonthDay(season.getAutumn());
|
||||
atMidnightOfFirstMonthDay(season.getWinter());
|
||||
if (useMeteorologicalSeason && season != null) {
|
||||
Calendar cal = season.getSpring();
|
||||
if (cal != null) {
|
||||
atMidnightOfFirstMonthDay(cal);
|
||||
}
|
||||
cal = season.getSummer();
|
||||
if (cal != null) {
|
||||
atMidnightOfFirstMonthDay(cal);
|
||||
}
|
||||
cal = season.getAutumn();
|
||||
if (cal != null) {
|
||||
atMidnightOfFirstMonthDay(cal);
|
||||
}
|
||||
cal = season.getWinter();
|
||||
if (cal != null) {
|
||||
atMidnightOfFirstMonthDay(cal);
|
||||
}
|
||||
}
|
||||
|
||||
season.setName(!isSouthernHemisphere ? getCurrentSeasonNameNorthern(calendar)
|
||||
: getCurrentSeasonNameSouthern(calendar));
|
||||
return season;
|
||||
if (season != null) {
|
||||
season.setName(!isSouthernHemisphere ? getCurrentSeasonNameNorthern(calendar)
|
||||
: getCurrentSeasonNameSouthern(calendar));
|
||||
return season;
|
||||
}
|
||||
return new Season();
|
||||
}
|
||||
|
||||
private void atMidnightOfFirstMonthDay(Calendar calendar) {
|
||||
@@ -75,19 +96,28 @@ public class SeasonCalc {
|
||||
/**
|
||||
* Returns the current season name for the northern hemisphere.
|
||||
*/
|
||||
@Nullable
|
||||
private SeasonName getCurrentSeasonNameNorthern(Calendar calendar) {
|
||||
Season currentSeason = this.currentSeason;
|
||||
if (currentSeason == null) {
|
||||
return null;
|
||||
}
|
||||
long currentMillis = calendar.getTimeInMillis();
|
||||
if (currentMillis < currentSeason.getSpring().getTimeInMillis()
|
||||
|| currentMillis >= currentSeason.getWinter().getTimeInMillis()) {
|
||||
Calendar spring = currentSeason.getSpring();
|
||||
Calendar summer = currentSeason.getSummer();
|
||||
Calendar autumn = currentSeason.getAutumn();
|
||||
Calendar winter = currentSeason.getWinter();
|
||||
if ((spring != null && currentMillis < spring.getTimeInMillis())
|
||||
|| (winter != null && currentMillis >= winter.getTimeInMillis())) {
|
||||
return SeasonName.WINTER;
|
||||
} else if (currentMillis >= currentSeason.getSpring().getTimeInMillis()
|
||||
&& currentMillis < currentSeason.getSummer().getTimeInMillis()) {
|
||||
} else if (spring != null && summer != null && currentMillis >= spring.getTimeInMillis()
|
||||
&& currentMillis < summer.getTimeInMillis()) {
|
||||
return SeasonName.SPRING;
|
||||
} else if (currentMillis >= currentSeason.getSummer().getTimeInMillis()
|
||||
&& currentMillis < currentSeason.getAutumn().getTimeInMillis()) {
|
||||
} else if (summer != null && autumn != null && currentMillis >= summer.getTimeInMillis()
|
||||
&& currentMillis < autumn.getTimeInMillis()) {
|
||||
return SeasonName.SUMMER;
|
||||
} else if (currentMillis >= currentSeason.getAutumn().getTimeInMillis()
|
||||
&& currentMillis < currentSeason.getWinter().getTimeInMillis()) {
|
||||
} else if (autumn != null && winter != null && currentMillis >= autumn.getTimeInMillis()
|
||||
&& currentMillis < winter.getTimeInMillis()) {
|
||||
return SeasonName.AUTUMN;
|
||||
}
|
||||
return null;
|
||||
@@ -96,19 +126,28 @@ public class SeasonCalc {
|
||||
/**
|
||||
* Returns the current season name for the southern hemisphere.
|
||||
*/
|
||||
@Nullable
|
||||
private SeasonName getCurrentSeasonNameSouthern(Calendar calendar) {
|
||||
Season currentSeason = this.currentSeason;
|
||||
if (currentSeason == null) {
|
||||
return null;
|
||||
}
|
||||
long currentMillis = calendar.getTimeInMillis();
|
||||
if (currentMillis < currentSeason.getAutumn().getTimeInMillis()
|
||||
|| currentMillis >= currentSeason.getSummer().getTimeInMillis()) {
|
||||
Calendar spring = currentSeason.getSpring();
|
||||
Calendar summer = currentSeason.getSummer();
|
||||
Calendar autumn = currentSeason.getAutumn();
|
||||
Calendar winter = currentSeason.getWinter();
|
||||
if ((autumn != null && currentMillis < autumn.getTimeInMillis())
|
||||
|| (summer != null && currentMillis >= summer.getTimeInMillis())) {
|
||||
return SeasonName.SUMMER;
|
||||
} else if (currentMillis >= currentSeason.getAutumn().getTimeInMillis()
|
||||
&& currentMillis < currentSeason.getWinter().getTimeInMillis()) {
|
||||
} else if (autumn != null && winter != null && currentMillis >= autumn.getTimeInMillis()
|
||||
&& currentMillis < winter.getTimeInMillis()) {
|
||||
return SeasonName.AUTUMN;
|
||||
} else if (currentMillis >= currentSeason.getWinter().getTimeInMillis()
|
||||
&& currentMillis < currentSeason.getSpring().getTimeInMillis()) {
|
||||
} else if (winter != null && spring != null && currentMillis >= winter.getTimeInMillis()
|
||||
&& currentMillis < spring.getTimeInMillis()) {
|
||||
return SeasonName.WINTER;
|
||||
} else if (currentMillis >= currentSeason.getSpring().getTimeInMillis()
|
||||
&& currentMillis < currentSeason.getSummer().getTimeInMillis()) {
|
||||
} else if (spring != null && summer != null && currentMillis >= spring.getTimeInMillis()
|
||||
&& currentMillis < summer.getTimeInMillis()) {
|
||||
return SeasonName.SPRING;
|
||||
}
|
||||
return null;
|
||||
@@ -117,14 +156,15 @@ public class SeasonCalc {
|
||||
/**
|
||||
* Calculates the date of the season.
|
||||
*/
|
||||
private Calendar calcEquiSol(int season, int year) {
|
||||
@Nullable
|
||||
private Calendar calcEquiSol(int season, int year, TimeZone zone, Locale locale) {
|
||||
double estimate = calcInitial(season, year);
|
||||
double t = (estimate - 2451545.0) / 36525;
|
||||
double w = 35999.373 * t - 2.47;
|
||||
double dl = 1 + 0.0334 * cosDeg(w) + 0.0007 * cosDeg(2 * w);
|
||||
double s = periodic24(t);
|
||||
double julianDate = estimate + ((0.00001 * s) / dl);
|
||||
return DateTimeUtils.toCalendar(julianDate);
|
||||
return DateTimeUtils.toCalendar(julianDate, zone, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+53
-32
@@ -18,9 +18,13 @@ import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.model.Eclipse;
|
||||
import org.openhab.binding.astro.internal.model.EclipseType;
|
||||
import org.openhab.binding.astro.internal.model.Position;
|
||||
@@ -37,6 +41,7 @@ import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
* @author Christoph Weitkamp - Introduced UoM
|
||||
* @implNote based on the calculations of http://www.suncalc.net
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SunCalc {
|
||||
private static final double J2000 = 2451545.0;
|
||||
private static final double SC = 1367; // Solar constant in W/m²
|
||||
@@ -69,7 +74,8 @@ public class SunCalc {
|
||||
/**
|
||||
* Calculates the sun position (azimuth and elevation).
|
||||
*/
|
||||
public void setPositionalInfo(Calendar calendar, double latitude, double longitude, Double altitude, Sun sun) {
|
||||
public void setPositionalInfo(Calendar calendar, double latitude, double longitude, @Nullable Double altitude,
|
||||
Sun sun) {
|
||||
double lw = -longitude * DEG2RAD;
|
||||
double phi = latitude * DEG2RAD;
|
||||
|
||||
@@ -96,7 +102,7 @@ public class SunCalc {
|
||||
/**
|
||||
* Calculates sun radiation data.
|
||||
*/
|
||||
private void setRadiationInfo(Calendar calendar, double elevation, Double altitude, Sun sun) {
|
||||
private void setRadiationInfo(Calendar calendar, double elevation, @Nullable Double altitude, Sun sun) {
|
||||
double sinAlpha = Math.sin(DEG2RAD * elevation);
|
||||
|
||||
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
|
||||
@@ -125,7 +131,7 @@ public class SunCalc {
|
||||
/**
|
||||
* Returns true, if the sun is up all day (no rise and set).
|
||||
*/
|
||||
private boolean isSunUpAllDay(Calendar calendar, double latitude, double longitude, Double altitude) {
|
||||
private boolean isSunUpAllDay(Calendar calendar, double latitude, double longitude, @Nullable Double altitude) {
|
||||
Calendar cal = DateTimeUtils.truncateToMidnight(calendar);
|
||||
Sun sun = new Sun();
|
||||
for (int minutes = 0; minutes <= MINUTES_PER_DAY; minutes += CURVE_TIME_INTERVAL) {
|
||||
@@ -141,13 +147,13 @@ public class SunCalc {
|
||||
/**
|
||||
* Calculates all sun rise and sets at the specified coordinates.
|
||||
*/
|
||||
public Sun getSunInfo(Calendar calendar, double latitude, double longitude, Double altitude,
|
||||
boolean useMeteorologicalSeason) {
|
||||
return getSunInfo(calendar, latitude, longitude, altitude, false, useMeteorologicalSeason);
|
||||
public Sun getSunInfo(Calendar calendar, double latitude, double longitude, @Nullable Double altitude,
|
||||
boolean useMeteorologicalSeason, TimeZone zone, Locale locale) {
|
||||
return getSunInfo(calendar, latitude, longitude, altitude, false, useMeteorologicalSeason, zone, locale);
|
||||
}
|
||||
|
||||
private Sun getSunInfo(Calendar calendar, double latitude, double longitude, Double altitude, boolean onlyAstro,
|
||||
boolean useMeteorologicalSeason) {
|
||||
private Sun getSunInfo(Calendar calendar, double latitude, double longitude, @Nullable Double altitude,
|
||||
boolean onlyAstro, boolean useMeteorologicalSeason, TimeZone zone, Locale locale) {
|
||||
double lw = -longitude * DEG2RAD;
|
||||
double phi = latitude * DEG2RAD;
|
||||
double j = DateTimeUtils.midnightDateToJulianDate(calendar) + 0.5;
|
||||
@@ -176,23 +182,31 @@ public class SunCalc {
|
||||
double jastro2 = getSunriseJulianDate(jtransit, jdark);
|
||||
|
||||
Sun sun = new Sun();
|
||||
sun.setAstroDawn(new Range(DateTimeUtils.toCalendar(jastro2), DateTimeUtils.toCalendar(jnau2)));
|
||||
sun.setAstroDusk(new Range(DateTimeUtils.toCalendar(jastro), DateTimeUtils.toCalendar(jdark)));
|
||||
sun.setAstroDawn(new Range(DateTimeUtils.toCalendar(jastro2, zone, locale),
|
||||
DateTimeUtils.toCalendar(jnau2, zone, locale)));
|
||||
sun.setAstroDusk(new Range(DateTimeUtils.toCalendar(jastro, zone, locale),
|
||||
DateTimeUtils.toCalendar(jdark, zone, locale)));
|
||||
|
||||
if (onlyAstro) {
|
||||
return sun;
|
||||
}
|
||||
|
||||
sun.setNoon(new Range(DateTimeUtils.toCalendar(jtransit),
|
||||
DateTimeUtils.toCalendar(jtransit + JD_ONE_MINUTE_FRACTION)));
|
||||
sun.setRise(new Range(DateTimeUtils.toCalendar(jrise), DateTimeUtils.toCalendar(jriseend)));
|
||||
sun.setSet(new Range(DateTimeUtils.toCalendar(jsetstart), DateTimeUtils.toCalendar(jset)));
|
||||
sun.setNoon(new Range(DateTimeUtils.toCalendar(jtransit, zone, locale),
|
||||
DateTimeUtils.toCalendar(jtransit + JD_ONE_MINUTE_FRACTION, zone, locale)));
|
||||
sun.setRise(new Range(DateTimeUtils.toCalendar(jrise, zone, locale),
|
||||
DateTimeUtils.toCalendar(jriseend, zone, locale)));
|
||||
sun.setSet(new Range(DateTimeUtils.toCalendar(jsetstart, zone, locale),
|
||||
DateTimeUtils.toCalendar(jset, zone, locale)));
|
||||
|
||||
sun.setCivilDawn(new Range(DateTimeUtils.toCalendar(jciv2), DateTimeUtils.toCalendar(jrise)));
|
||||
sun.setCivilDusk(new Range(DateTimeUtils.toCalendar(jset), DateTimeUtils.toCalendar(jnau)));
|
||||
sun.setCivilDawn(new Range(DateTimeUtils.toCalendar(jciv2, zone, locale),
|
||||
DateTimeUtils.toCalendar(jrise, zone, locale)));
|
||||
sun.setCivilDusk(
|
||||
new Range(DateTimeUtils.toCalendar(jset, zone, locale), DateTimeUtils.toCalendar(jnau, zone, locale)));
|
||||
|
||||
sun.setNauticDawn(new Range(DateTimeUtils.toCalendar(jnau2), DateTimeUtils.toCalendar(jciv2)));
|
||||
sun.setNauticDusk(new Range(DateTimeUtils.toCalendar(jnau), DateTimeUtils.toCalendar(jastro)));
|
||||
sun.setNauticDawn(new Range(DateTimeUtils.toCalendar(jnau2, zone, locale),
|
||||
DateTimeUtils.toCalendar(jciv2, zone, locale)));
|
||||
sun.setNauticDusk(new Range(DateTimeUtils.toCalendar(jnau, zone, locale),
|
||||
DateTimeUtils.toCalendar(jastro, zone, locale)));
|
||||
|
||||
boolean isSunUpAllDay = isSunUpAllDay(calendar, latitude, longitude, altitude);
|
||||
|
||||
@@ -210,23 +224,26 @@ public class SunCalc {
|
||||
|
||||
// morning night
|
||||
Sun sunYesterday = getSunInfo(addDays(calendar, -1), latitude, longitude, altitude, true,
|
||||
useMeteorologicalSeason);
|
||||
useMeteorologicalSeason, zone, locale);
|
||||
Range morningNightRange = null;
|
||||
if (sunYesterday.getAstroDusk().getEnd() != null
|
||||
&& DateTimeUtils.isSameDay(sunYesterday.getAstroDusk().getEnd(), calendar)) {
|
||||
morningNightRange = new Range(sunYesterday.getAstroDusk().getEnd(), sun.getAstroDawn().getStart());
|
||||
} else if (isSunUpAllDay || sun.getAstroDawn().getStart() == null) {
|
||||
Range range, range2;
|
||||
if ((range = sunYesterday.getAstroDusk()) != null && range.getEnd() != null
|
||||
&& DateTimeUtils.isSameDay(range.getEnd(), calendar)) {
|
||||
morningNightRange = new Range(range.getEnd(),
|
||||
(range2 = sun.getAstroDawn()) == null ? null : range2.getStart());
|
||||
} else if (isSunUpAllDay || (range2 = sun.getAstroDawn()) == null || range2.getStart() == null) {
|
||||
morningNightRange = new Range();
|
||||
} else {
|
||||
morningNightRange = new Range(DateTimeUtils.truncateToMidnight(calendar), sun.getAstroDawn().getStart());
|
||||
morningNightRange = new Range(DateTimeUtils.truncateToMidnight(calendar),
|
||||
(range2 = sun.getAstroDawn()) == null ? null : range2.getStart());
|
||||
}
|
||||
sun.setMorningNight(morningNightRange);
|
||||
|
||||
// evening night
|
||||
Range eveningNightRange = null;
|
||||
if (sun.getAstroDusk().getEnd() != null && DateTimeUtils.isSameDay(sun.getAstroDusk().getEnd(), calendar)) {
|
||||
eveningNightRange = new Range(sun.getAstroDusk().getEnd(),
|
||||
DateTimeUtils.truncateToMidnight(addDays(calendar, 1)));
|
||||
if ((range = sun.getAstroDusk()) != null && range.getEnd() != null
|
||||
&& DateTimeUtils.isSameDay(range.getEnd(), calendar)) {
|
||||
eveningNightRange = new Range(range.getEnd(), DateTimeUtils.truncateToMidnight(addDays(calendar, 1)));
|
||||
} else {
|
||||
eveningNightRange = new Range();
|
||||
}
|
||||
@@ -237,8 +254,9 @@ public class SunCalc {
|
||||
sun.setNight(new Range());
|
||||
} else {
|
||||
Sun sunTomorrow = getSunInfo(addDays(calendar, 1), latitude, longitude, altitude, true,
|
||||
useMeteorologicalSeason);
|
||||
sun.setNight(new Range(sun.getAstroDusk().getEnd(), sunTomorrow.getAstroDawn().getStart()));
|
||||
useMeteorologicalSeason, zone, locale);
|
||||
sun.setNight(new Range((range = sun.getAstroDusk()) == null ? null : range.getEnd(),
|
||||
(range2 = sunTomorrow.getAstroDawn()) == null ? null : range2.getStart()));
|
||||
}
|
||||
|
||||
// eclipse
|
||||
@@ -247,14 +265,17 @@ public class SunCalc {
|
||||
|
||||
eclipse.getKinds().forEach(eclipseKind -> {
|
||||
double jdate = mc.getEclipse(calendar, EclipseType.SUN, j, eclipseKind);
|
||||
eclipse.set(eclipseKind, DateTimeUtils.toCalendar(jdate), new Position());
|
||||
Calendar eclipseDate = DateTimeUtils.toCalendar(jdate, zone, locale);
|
||||
if (eclipseDate != null) {
|
||||
eclipse.set(eclipseKind, eclipseDate, new Position());
|
||||
}
|
||||
});
|
||||
|
||||
SunZodiacCalc zodiacCalc = new SunZodiacCalc();
|
||||
SunZodiacCalc zodiacCalc = new SunZodiacCalc(zone, locale);
|
||||
zodiacCalc.getZodiac(calendar).ifPresent(z -> sun.setZodiac(z));
|
||||
|
||||
SeasonCalc seasonCalc = new SeasonCalc();
|
||||
sun.setSeason(seasonCalc.getSeason(calendar, latitude, useMeteorologicalSeason));
|
||||
sun.setSeason(seasonCalc.getSeason(calendar, latitude, useMeteorologicalSeason, zone, locale));
|
||||
|
||||
// phase
|
||||
for (Entry<SunPhaseName, Range> rangeEntry : sortByValue(sun.getAllRanges()).entrySet()) {
|
||||
|
||||
+23
-13
@@ -16,8 +16,10 @@ import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.model.SunZodiac;
|
||||
@@ -33,6 +35,14 @@ import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
public class SunZodiacCalc {
|
||||
private Map<Integer, List<SunZodiac>> zodiacsByYear = new HashMap<>();
|
||||
|
||||
private final TimeZone zone;
|
||||
private final Locale locale;
|
||||
|
||||
public SunZodiacCalc(TimeZone zone, Locale locale) {
|
||||
this.zone = zone;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the zodiac for the specified calendar.
|
||||
*/
|
||||
@@ -58,31 +68,31 @@ public class SunZodiacCalc {
|
||||
List<SunZodiac> zodiacs = new ArrayList<>();
|
||||
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.ARIES,
|
||||
DateTimeUtils.getRange(year, Calendar.MARCH, 21, year, Calendar.APRIL, 19)));
|
||||
DateTimeUtils.getRange(year, Calendar.MARCH, 21, year, Calendar.APRIL, 19, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.TAURUS,
|
||||
DateTimeUtils.getRange(year, Calendar.APRIL, 20, year, Calendar.MAY, 20)));
|
||||
DateTimeUtils.getRange(year, Calendar.APRIL, 20, year, Calendar.MAY, 20, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.GEMINI,
|
||||
DateTimeUtils.getRange(year, Calendar.MAY, 21, year, Calendar.JUNE, 20)));
|
||||
DateTimeUtils.getRange(year, Calendar.MAY, 21, year, Calendar.JUNE, 20, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.CANCER,
|
||||
DateTimeUtils.getRange(year, Calendar.JUNE, 21, year, Calendar.JULY, 22)));
|
||||
DateTimeUtils.getRange(year, Calendar.JUNE, 21, year, Calendar.JULY, 22, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.LEO,
|
||||
DateTimeUtils.getRange(year, Calendar.JULY, 23, year, Calendar.AUGUST, 22)));
|
||||
DateTimeUtils.getRange(year, Calendar.JULY, 23, year, Calendar.AUGUST, 22, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.VIRGO,
|
||||
DateTimeUtils.getRange(year, Calendar.AUGUST, 23, year, Calendar.SEPTEMBER, 22)));
|
||||
DateTimeUtils.getRange(year, Calendar.AUGUST, 23, year, Calendar.SEPTEMBER, 22, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.LIBRA,
|
||||
DateTimeUtils.getRange(year, Calendar.SEPTEMBER, 23, year, Calendar.OCTOBER, 22)));
|
||||
DateTimeUtils.getRange(year, Calendar.SEPTEMBER, 23, year, Calendar.OCTOBER, 22, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.SCORPIO,
|
||||
DateTimeUtils.getRange(year, Calendar.OCTOBER, 23, year, Calendar.NOVEMBER, 21)));
|
||||
DateTimeUtils.getRange(year, Calendar.OCTOBER, 23, year, Calendar.NOVEMBER, 21, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.SAGITTARIUS,
|
||||
DateTimeUtils.getRange(year, Calendar.NOVEMBER, 22, year, Calendar.DECEMBER, 21)));
|
||||
DateTimeUtils.getRange(year, Calendar.NOVEMBER, 22, year, Calendar.DECEMBER, 21, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.CAPRICORN,
|
||||
DateTimeUtils.getRange(year, Calendar.DECEMBER, 22, year + 1, Calendar.JANUARY, 19)));
|
||||
DateTimeUtils.getRange(year, Calendar.DECEMBER, 22, year + 1, Calendar.JANUARY, 19, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.CAPRICORN,
|
||||
DateTimeUtils.getRange(year - 1, Calendar.DECEMBER, 22, year, Calendar.JANUARY, 19)));
|
||||
DateTimeUtils.getRange(year - 1, Calendar.DECEMBER, 22, year, Calendar.JANUARY, 19, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.AQUARIUS,
|
||||
DateTimeUtils.getRange(year, Calendar.JANUARY, 20, year, Calendar.FEBRUARY, 18)));
|
||||
DateTimeUtils.getRange(year, Calendar.JANUARY, 20, year, Calendar.FEBRUARY, 18, zone, locale)));
|
||||
zodiacs.add(new SunZodiac(ZodiacSign.PISCES,
|
||||
DateTimeUtils.getRange(year, Calendar.FEBRUARY, 19, year, Calendar.MARCH, 20)));
|
||||
DateTimeUtils.getRange(year, Calendar.FEBRUARY, 19, year, Calendar.MARCH, 20, zone, locale)));
|
||||
|
||||
return zodiacs;
|
||||
}
|
||||
|
||||
+9
-6
@@ -59,8 +59,9 @@ public class AstroDiscoveryService extends AbstractDiscoveryService {
|
||||
|
||||
private final LocationProvider locationProvider;
|
||||
|
||||
// All access must be guarded by "this"
|
||||
private @Nullable ScheduledFuture<?> astroDiscoveryJob;
|
||||
private @Nullable PointType previousLocation;
|
||||
private volatile @Nullable PointType previousLocation;
|
||||
|
||||
@Activate
|
||||
public AstroDiscoveryService(final @Reference LocationProvider locationProvider,
|
||||
@@ -85,7 +86,7 @@ public class AstroDiscoveryService extends AbstractDiscoveryService {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startBackgroundDiscovery() {
|
||||
protected synchronized void startBackgroundDiscovery() {
|
||||
if (astroDiscoveryJob == null) {
|
||||
astroDiscoveryJob = scheduler.scheduleWithFixedDelay(() -> {
|
||||
PointType currentLocation = locationProvider.getLocation();
|
||||
@@ -103,11 +104,13 @@ public class AstroDiscoveryService extends AbstractDiscoveryService {
|
||||
@Override
|
||||
protected void stopBackgroundDiscovery() {
|
||||
logger.debug("Stopping Astro device background discovery");
|
||||
ScheduledFuture<?> discoveryJob = astroDiscoveryJob;
|
||||
if (discoveryJob != null) {
|
||||
discoveryJob.cancel(true);
|
||||
synchronized (this) {
|
||||
ScheduledFuture<?> discoveryJob = astroDiscoveryJob;
|
||||
if (discoveryJob != null) {
|
||||
discoveryJob.cancel(true);
|
||||
}
|
||||
astroDiscoveryJob = null;
|
||||
}
|
||||
astroDiscoveryJob = null;
|
||||
}
|
||||
|
||||
public void createResults(PointType location) {
|
||||
|
||||
+38
-16
@@ -26,7 +26,9 @@ import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
@@ -44,6 +46,7 @@ import org.openhab.binding.astro.internal.job.PositionalJob;
|
||||
import org.openhab.binding.astro.internal.model.Planet;
|
||||
import org.openhab.binding.astro.internal.model.Position;
|
||||
import org.openhab.binding.astro.internal.util.PropertyUtils;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
@@ -77,20 +80,27 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
|
||||
protected final TimeZoneProvider timeZoneProvider;
|
||||
|
||||
protected final LocaleProvider localeProvider;
|
||||
|
||||
private final Lock monitor = new ReentrantLock();
|
||||
|
||||
// All access must be guarded by "monitor"
|
||||
private final Set<ScheduledFuture<?>> scheduledFutures = new HashSet<>();
|
||||
|
||||
// All access must be guarded by "monitor"
|
||||
private boolean linkedPositionalChannels;
|
||||
|
||||
protected AstroThingConfig thingConfig = new AstroThingConfig();
|
||||
|
||||
// All access must be guarded by "monitor"
|
||||
private @Nullable ScheduledCompletableFuture<?> dailyJob;
|
||||
|
||||
public AstroThingHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider) {
|
||||
public AstroThingHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider,
|
||||
LocaleProvider localeProvider) {
|
||||
super(thing);
|
||||
this.cronScheduler = scheduler;
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.localeProvider = localeProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -175,8 +185,8 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
}
|
||||
try {
|
||||
AstroChannelConfig config = channel.getConfiguration().as(AstroChannelConfig.class);
|
||||
updateState(channelUID,
|
||||
PropertyUtils.getState(channelUID, config, planet, timeZoneProvider.getTimeZone()));
|
||||
updateState(channelUID, PropertyUtils.getState(channelUID, config, planet,
|
||||
TimeZone.getTimeZone(timeZoneProvider.getTimeZone())));
|
||||
} catch (Exception ex) {
|
||||
logger.error("Can't update state for channel {} : {}", channelUID, ex.getMessage(), ex);
|
||||
}
|
||||
@@ -193,9 +203,10 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
try {
|
||||
stopJobs();
|
||||
if (getThing().getStatus() == ONLINE) {
|
||||
String thingUID = getThing().getUID().toString();
|
||||
TimeZone zone = TimeZone.getTimeZone(timeZoneProvider.getTimeZone());
|
||||
Locale locale = localeProvider.getLocale();
|
||||
// Daily Job
|
||||
Job runnable = getDailyJob();
|
||||
Job runnable = getDailyJob(zone, locale);
|
||||
dailyJob = cronScheduler.schedule(runnable, DAILY_MIDNIGHT);
|
||||
logger.debug("Scheduled {} at midnight", dailyJob);
|
||||
// Execute daily startup job immediately
|
||||
@@ -205,7 +216,7 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
// Use scheduleAtFixedRate to avoid time drift associated with scheduleWithFixedDelay
|
||||
linkedPositionalChannels = isPositionalChannelLinked();
|
||||
if (linkedPositionalChannels) {
|
||||
Job positionalJob = new PositionalJob(thingUID);
|
||||
Job positionalJob = new PositionalJob(this);
|
||||
ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(positionalJob, 0, thingConfig.interval,
|
||||
TimeUnit.SECONDS);
|
||||
scheduledFutures.add(future);
|
||||
@@ -258,10 +269,16 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
*/
|
||||
private void linkedChannelChange(ChannelUID channelUID) {
|
||||
if (Arrays.asList(getPositionalChannelIds()).contains(channelUID.getId())) {
|
||||
boolean oldValue = linkedPositionalChannels;
|
||||
linkedPositionalChannels = isPositionalChannelLinked();
|
||||
if (oldValue != linkedPositionalChannels) {
|
||||
restartJobs();
|
||||
boolean newValue = isPositionalChannelLinked();
|
||||
monitor.lock();
|
||||
try {
|
||||
boolean oldValue = linkedPositionalChannels;
|
||||
linkedPositionalChannels = newValue;
|
||||
if (oldValue != linkedPositionalChannels) {
|
||||
restartJobs();
|
||||
}
|
||||
} finally {
|
||||
monitor.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,12 +330,17 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
private void tidyScheduledFutures() {
|
||||
for (Iterator<ScheduledFuture<?>> iterator = scheduledFutures.iterator(); iterator.hasNext();) {
|
||||
ScheduledFuture<?> future = iterator.next();
|
||||
if (future.isDone()) {
|
||||
logger.trace("Tidying up done future {}", future);
|
||||
iterator.remove();
|
||||
monitor.lock();
|
||||
try {
|
||||
for (Iterator<ScheduledFuture<?>> iterator = scheduledFutures.iterator(); iterator.hasNext();) {
|
||||
ScheduledFuture<?> future = iterator.next();
|
||||
if (future.isDone()) {
|
||||
logger.trace("Tidying up done future {}", future);
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
monitor.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +369,7 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
/**
|
||||
* Returns the daily calculation {@link Job} (cannot be {@code null})
|
||||
*/
|
||||
protected abstract Job getDailyJob();
|
||||
protected abstract Job getDailyJob(TimeZone zone, Locale locale);
|
||||
|
||||
public abstract @Nullable Position getPositionAt(ZonedDateTime date);
|
||||
|
||||
|
||||
+21
-12
@@ -12,9 +12,12 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
@@ -24,6 +27,7 @@ import org.openhab.binding.astro.internal.job.Job;
|
||||
import org.openhab.binding.astro.internal.model.Moon;
|
||||
import org.openhab.binding.astro.internal.model.Planet;
|
||||
import org.openhab.binding.astro.internal.model.Position;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@@ -40,24 +44,29 @@ public class MoonHandler extends AstroThingHandler {
|
||||
private final String[] positionalChannelIds = new String[] { "phase#name", "phase#age", "phase#agePercent",
|
||||
"phase#ageDegree", "phase#illumination", "position#azimuth", "position#elevation", "zodiac#sign" };
|
||||
private final MoonCalc moonCalc = new MoonCalc();
|
||||
private @NonNullByDefault({}) Moon moon;
|
||||
private volatile @Nullable Moon moon;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public MoonHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider) {
|
||||
super(thing, scheduler, timeZoneProvider);
|
||||
public MoonHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider,
|
||||
LocaleProvider localeProvider) {
|
||||
super(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishPositionalInfo() {
|
||||
moon = getMoonAt(ZonedDateTime.now());
|
||||
ZoneId zoneId = timeZoneProvider.getTimeZone();
|
||||
TimeZone zone = TimeZone.getTimeZone(zoneId);
|
||||
Locale locale = localeProvider.getLocale();
|
||||
Moon moon = getMoonAt(ZonedDateTime.now(zoneId), locale);
|
||||
Double latitude = thingConfig.latitude;
|
||||
Double longitude = thingConfig.longitude;
|
||||
moonCalc.setPositionalInfo(Calendar.getInstance(), latitude != null ? latitude : 0,
|
||||
longitude != null ? longitude : 0, moon);
|
||||
moonCalc.setPositionalInfo(Calendar.getInstance(zone, locale), latitude != null ? latitude : 0,
|
||||
longitude != null ? longitude : 0, moon, zone, locale);
|
||||
|
||||
moon.getEclipse().setElevations(this, timeZoneProvider);
|
||||
this.moon = moon;
|
||||
|
||||
publishPlanet();
|
||||
}
|
||||
@@ -79,24 +88,24 @@ public class MoonHandler extends AstroThingHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Job getDailyJob() {
|
||||
return new DailyJobMoon(thing.getUID().getAsString(), this);
|
||||
protected Job getDailyJob(TimeZone zone, Locale locale) {
|
||||
return new DailyJobMoon(this, zone, locale);
|
||||
}
|
||||
|
||||
private Moon getMoonAt(ZonedDateTime date) {
|
||||
private Moon getMoonAt(ZonedDateTime date, Locale locale) {
|
||||
Double latitude = thingConfig.latitude;
|
||||
Double longitude = thingConfig.longitude;
|
||||
return moonCalc.getMoonInfo(GregorianCalendar.from(date), latitude != null ? latitude : 0,
|
||||
longitude != null ? longitude : 0);
|
||||
longitude != null ? longitude : 0, TimeZone.getTimeZone(date.getZone()), locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Position getPositionAt(ZonedDateTime date) {
|
||||
Moon localMoon = getMoonAt(date);
|
||||
Moon localMoon = getMoonAt(date, Locale.ROOT);
|
||||
Double latitude = thingConfig.latitude;
|
||||
Double longitude = thingConfig.longitude;
|
||||
moonCalc.setPositionalInfo(GregorianCalendar.from(date), latitude != null ? latitude : 0,
|
||||
longitude != null ? longitude : 0, localMoon);
|
||||
longitude != null ? longitude : 0, localMoon, TimeZone.getTimeZone(date.getZone()), Locale.ROOT);
|
||||
return localMoon.getPosition();
|
||||
}
|
||||
}
|
||||
|
||||
+19
-10
@@ -12,9 +12,12 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
@@ -27,6 +30,7 @@ import org.openhab.binding.astro.internal.model.Radiation;
|
||||
import org.openhab.binding.astro.internal.model.Range;
|
||||
import org.openhab.binding.astro.internal.model.Sun;
|
||||
import org.openhab.binding.astro.internal.model.SunPhaseName;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@@ -43,25 +47,30 @@ public class SunHandler extends AstroThingHandler {
|
||||
private final String[] positionalChannelIds = new String[] { "position#azimuth", "position#elevation",
|
||||
"radiation#direct", "radiation#diffuse", "radiation#total" };
|
||||
private final SunCalc sunCalc = new SunCalc();
|
||||
private @NonNullByDefault({}) Sun sun;
|
||||
private volatile @Nullable Sun sun;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public SunHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider) {
|
||||
super(thing, scheduler, timeZoneProvider);
|
||||
public SunHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider,
|
||||
LocaleProvider localeProvider) {
|
||||
super(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void publishPositionalInfo() {
|
||||
sun = getSunAt(ZonedDateTime.now());
|
||||
ZoneId zoneId = timeZoneProvider.getTimeZone();
|
||||
TimeZone zone = TimeZone.getTimeZone(zoneId);
|
||||
Locale locale = localeProvider.getLocale();
|
||||
Sun sun = getSunAt(ZonedDateTime.now(zoneId));
|
||||
Double latitude = thingConfig.latitude;
|
||||
Double longitude = thingConfig.longitude;
|
||||
Double altitude = thingConfig.altitude;
|
||||
sunCalc.setPositionalInfo(Calendar.getInstance(), latitude != null ? latitude : 0,
|
||||
sunCalc.setPositionalInfo(Calendar.getInstance(zone, locale), latitude != null ? latitude : 0,
|
||||
longitude != null ? longitude : 0, altitude != null ? altitude : 0, sun);
|
||||
|
||||
sun.getEclipse().setElevations(this, timeZoneProvider);
|
||||
this.sun = sun;
|
||||
|
||||
publishPlanet();
|
||||
}
|
||||
@@ -83,8 +92,8 @@ public class SunHandler extends AstroThingHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Job getDailyJob() {
|
||||
return new DailyJobSun(thing.getUID().getAsString(), this);
|
||||
protected Job getDailyJob(TimeZone zone, Locale locale) {
|
||||
return new DailyJobSun(this, zone, locale);
|
||||
}
|
||||
|
||||
private Sun getSunAt(ZonedDateTime date) {
|
||||
@@ -92,8 +101,8 @@ public class SunHandler extends AstroThingHandler {
|
||||
Double longitude = thingConfig.longitude;
|
||||
Double altitude = thingConfig.altitude;
|
||||
return sunCalc.getSunInfo(GregorianCalendar.from(date), latitude != null ? latitude : 0,
|
||||
longitude != null ? longitude : 0, altitude != null ? altitude : 0,
|
||||
thingConfig.useMeteorologicalSeason);
|
||||
longitude != null ? longitude : 0, altitude != null ? altitude : 0, thingConfig.useMeteorologicalSeason,
|
||||
TimeZone.getTimeZone(timeZoneProvider.getTimeZone()), Locale.ROOT);
|
||||
}
|
||||
|
||||
private Sun getPositionedSunAt(ZonedDateTime date) {
|
||||
@@ -110,7 +119,7 @@ public class SunHandler extends AstroThingHandler {
|
||||
Range eventRange = getSunAt(date).getAllRanges().get(sunPhase);
|
||||
if (eventRange != null) {
|
||||
Calendar cal = begin ? eventRange.getStart() : eventRange.getEnd();
|
||||
return ZonedDateTime.ofInstant(cal.toInstant(), date.getZone());
|
||||
return cal == null ? null : ZonedDateTime.ofInstant(cal.toInstant(), date.getZone());
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
+6
-5
@@ -13,6 +13,7 @@
|
||||
package org.openhab.binding.astro.internal.job;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
|
||||
/**
|
||||
* This class contains the default methods required for different jobs
|
||||
@@ -22,15 +23,15 @@ import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@NonNullByDefault
|
||||
public abstract class AbstractJob implements Job {
|
||||
|
||||
private final String thingUID;
|
||||
protected final AstroThingHandler handler;
|
||||
|
||||
public AbstractJob(String thingUID) {
|
||||
this.thingUID = thingUID;
|
||||
public AbstractJob(AstroThingHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getThingUID() {
|
||||
return thingUID;
|
||||
public AstroThingHandler getHandler() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+10
-8
@@ -16,6 +16,7 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
|
||||
/**
|
||||
* {@link CompositeJob} comprises multiple {@link Job}s to be executed in order
|
||||
@@ -31,18 +32,18 @@ public final class CompositeJob extends AbstractJob {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thingUID thing UID
|
||||
* @param handler thing thing handler
|
||||
* @param jobs the jobs to execute
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code jobs} is {@code null} or empty
|
||||
*/
|
||||
public CompositeJob(String thingUID, List<Job> jobs) {
|
||||
super(thingUID);
|
||||
public CompositeJob(AstroThingHandler handler, List<Job> jobs) {
|
||||
super(handler);
|
||||
|
||||
this.jobs = jobs;
|
||||
this.jobs = List.copyOf(jobs);
|
||||
|
||||
boolean notMatched = jobs.stream().anyMatch(j -> !j.getThingUID().equals(thingUID));
|
||||
checkArgument(!notMatched, "The jobs must associate the same thing UID");
|
||||
boolean notMatched = jobs.stream().anyMatch(j -> !j.getHandler().equals(handler));
|
||||
checkArgument(!notMatched, "The jobs must associate the same thing handler");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,8 +51,9 @@ public final class CompositeJob extends AbstractJob {
|
||||
jobs.forEach(j -> {
|
||||
try {
|
||||
j.run();
|
||||
} catch (RuntimeException ex) {
|
||||
LOGGER.warn("Job execution failed.", ex);
|
||||
} catch (Exception e) {
|
||||
logger.warn("Job execution of \"{}\" failed: {}", j, e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
+70
-35
@@ -16,6 +16,8 @@ import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
|
||||
import static org.openhab.binding.astro.internal.job.Job.scheduleEvent;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
@@ -33,57 +35,90 @@ import org.openhab.binding.astro.internal.model.Planet;
|
||||
@NonNullByDefault
|
||||
public final class DailyJobMoon extends AbstractJob {
|
||||
|
||||
private final AstroThingHandler handler;
|
||||
public final TimeZone zone;
|
||||
public final Locale locale;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thingUID the Thing UID
|
||||
* @param handler the {@link AstroThingHandler} instance
|
||||
* @throws IllegalArgumentException if {@code thingUID} or {@code handler} is {@code null}
|
||||
*/
|
||||
public DailyJobMoon(String thingUID, AstroThingHandler handler) {
|
||||
super(thingUID);
|
||||
this.handler = handler;
|
||||
public DailyJobMoon(AstroThingHandler handler, TimeZone zone, Locale locale) {
|
||||
super(handler);
|
||||
this.zone = zone;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
handler.publishDailyInfo();
|
||||
String thingUID = getThingUID();
|
||||
LOGGER.debug("Scheduled Astro event-jobs for thing {}", thingUID);
|
||||
|
||||
Planet planet = handler.getPlanet();
|
||||
if (planet == null) {
|
||||
LOGGER.error("Planet not instantiated");
|
||||
return;
|
||||
}
|
||||
Moon moon = (Moon) planet;
|
||||
scheduleEvent(thingUID, handler, moon.getRise().getStart(), EVENT_START, EVENT_CHANNEL_ID_RISE, false);
|
||||
scheduleEvent(thingUID, handler, moon.getSet().getEnd(), EVENT_END, EVENT_CHANNEL_ID_SET, false);
|
||||
|
||||
MoonPhase moonPhase = moon.getPhase();
|
||||
scheduleEvent(thingUID, handler, moonPhase.getFirstQuarter(), EVENT_PHASE_FIRST_QUARTER,
|
||||
EVENT_CHANNEL_ID_MOON_PHASE, false);
|
||||
scheduleEvent(thingUID, handler, moonPhase.getThirdQuarter(), EVENT_PHASE_THIRD_QUARTER,
|
||||
EVENT_CHANNEL_ID_MOON_PHASE, false);
|
||||
scheduleEvent(thingUID, handler, moonPhase.getFull(), EVENT_PHASE_FULL, EVENT_CHANNEL_ID_MOON_PHASE, false);
|
||||
scheduleEvent(thingUID, handler, moonPhase.getNew(), EVENT_PHASE_NEW, EVENT_CHANNEL_ID_MOON_PHASE, false);
|
||||
|
||||
Eclipse eclipse = moon.getEclipse();
|
||||
eclipse.getKinds().forEach(eclipseKind -> {
|
||||
Calendar eclipseDate = eclipse.getDate(eclipseKind);
|
||||
if (eclipseDate != null) {
|
||||
scheduleEvent(thingUID, handler, eclipseDate, eclipseKind.toString(), EVENT_CHANNEL_ID_ECLIPSE, false);
|
||||
try {
|
||||
handler.publishDailyInfo();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Scheduled Astro event-jobs for thing {}", handler.getThing().getUID());
|
||||
}
|
||||
});
|
||||
|
||||
scheduleEvent(thingUID, handler, moon.getPerigee().getDate(), EVENT_PERIGEE, EVENT_CHANNEL_ID_PERIGEE, false);
|
||||
scheduleEvent(thingUID, handler, moon.getApogee().getDate(), EVENT_APOGEE, EVENT_CHANNEL_ID_APOGEE, false);
|
||||
Planet planet = handler.getPlanet();
|
||||
if (planet == null) {
|
||||
logger.error("Planet not instantiated");
|
||||
return;
|
||||
}
|
||||
Moon moon = (Moon) planet;
|
||||
Calendar cal = moon.getRise().getStart();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_START, EVENT_CHANNEL_ID_RISE, false, zone, locale);
|
||||
}
|
||||
cal = moon.getSet().getEnd();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_END, EVENT_CHANNEL_ID_SET, false, zone, locale);
|
||||
}
|
||||
|
||||
MoonPhase moonPhase = moon.getPhase();
|
||||
cal = moonPhase.getFirstQuarter();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_PHASE_FIRST_QUARTER, EVENT_CHANNEL_ID_MOON_PHASE, false, zone,
|
||||
locale);
|
||||
}
|
||||
cal = moonPhase.getThirdQuarter();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_PHASE_THIRD_QUARTER, EVENT_CHANNEL_ID_MOON_PHASE, false, zone,
|
||||
locale);
|
||||
}
|
||||
cal = moonPhase.getFull();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_PHASE_FULL, EVENT_CHANNEL_ID_MOON_PHASE, false, zone, locale);
|
||||
}
|
||||
cal = moonPhase.getNew();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_PHASE_NEW, EVENT_CHANNEL_ID_MOON_PHASE, false, zone, locale);
|
||||
}
|
||||
|
||||
Eclipse eclipse = moon.getEclipse();
|
||||
eclipse.getKinds().forEach(eclipseKind -> {
|
||||
Calendar eclipseDate = eclipse.getDate(eclipseKind);
|
||||
if (eclipseDate != null) {
|
||||
scheduleEvent(handler, eclipseDate, eclipseKind.toString(), EVENT_CHANNEL_ID_ECLIPSE, false, zone,
|
||||
locale);
|
||||
}
|
||||
});
|
||||
|
||||
cal = moon.getPerigee().getDate();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_PERIGEE, EVENT_CHANNEL_ID_PERIGEE, false, zone, locale);
|
||||
}
|
||||
cal = moon.getApogee().getDate();
|
||||
if (cal != null) {
|
||||
scheduleEvent(handler, cal, EVENT_APOGEE, EVENT_CHANNEL_ID_APOGEE, false, zone, locale);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("The daily moon job execution for \"{}\" failed: {}", handler.getThing().getUID(),
|
||||
e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Daily job moon " + getThingUID();
|
||||
return "Daily job moon " + handler.getThing().getUID();
|
||||
}
|
||||
}
|
||||
|
||||
+130
-50
@@ -17,12 +17,16 @@ import static org.openhab.binding.astro.internal.job.Job.*;
|
||||
import static org.openhab.binding.astro.internal.model.SunPhaseName.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
import org.openhab.binding.astro.internal.model.Eclipse;
|
||||
import org.openhab.binding.astro.internal.model.Planet;
|
||||
import org.openhab.binding.astro.internal.model.Range;
|
||||
import org.openhab.binding.astro.internal.model.Sun;
|
||||
import org.openhab.binding.astro.internal.model.SunZodiac;
|
||||
|
||||
/**
|
||||
* Daily scheduled jobs For Sun planet
|
||||
@@ -33,74 +37,150 @@ import org.openhab.binding.astro.internal.model.Sun;
|
||||
@NonNullByDefault
|
||||
public final class DailyJobSun extends AbstractJob {
|
||||
|
||||
private final AstroThingHandler handler;
|
||||
private final TimeZone zone;
|
||||
private final Locale locale;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thingUID the Thing UID
|
||||
* @param handler the {@link AstroThingHandler} instance
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code thingUID} or {@code handler} is {@code null}
|
||||
*/
|
||||
public DailyJobSun(String thingUID, AstroThingHandler handler) {
|
||||
super(thingUID);
|
||||
this.handler = handler;
|
||||
public DailyJobSun(AstroThingHandler handler, TimeZone zone, Locale locale) {
|
||||
super(handler);
|
||||
this.zone = zone;
|
||||
this.locale = locale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
handler.publishDailyInfo();
|
||||
String thingUID = getThingUID();
|
||||
LOGGER.debug("Scheduled Astro event-jobs for thing {}", thingUID);
|
||||
|
||||
Planet planet = handler.getPlanet();
|
||||
if (planet == null) {
|
||||
LOGGER.error("Planet not instantiated");
|
||||
return;
|
||||
}
|
||||
Sun sun = (Sun) planet;
|
||||
scheduleRange(thingUID, handler, sun.getRise(), EVENT_CHANNEL_ID_RISE);
|
||||
scheduleRange(thingUID, handler, sun.getSet(), EVENT_CHANNEL_ID_SET);
|
||||
scheduleRange(thingUID, handler, sun.getNoon(), EVENT_CHANNEL_ID_NOON);
|
||||
scheduleRange(thingUID, handler, sun.getNight(), EVENT_CHANNEL_ID_NIGHT);
|
||||
scheduleRange(thingUID, handler, sun.getMorningNight(), EVENT_CHANNEL_ID_MORNING_NIGHT);
|
||||
scheduleRange(thingUID, handler, sun.getAstroDawn(), EVENT_CHANNEL_ID_ASTRO_DAWN);
|
||||
scheduleRange(thingUID, handler, sun.getNauticDawn(), EVENT_CHANNEL_ID_NAUTIC_DAWN);
|
||||
scheduleRange(thingUID, handler, sun.getCivilDawn(), EVENT_CHANNEL_ID_CIVIL_DAWN);
|
||||
scheduleRange(thingUID, handler, sun.getAstroDusk(), EVENT_CHANNEL_ID_ASTRO_DUSK);
|
||||
scheduleRange(thingUID, handler, sun.getNauticDusk(), EVENT_CHANNEL_ID_NAUTIC_DUSK);
|
||||
scheduleRange(thingUID, handler, sun.getCivilDusk(), EVENT_CHANNEL_ID_CIVIL_DUSK);
|
||||
scheduleRange(thingUID, handler, sun.getEveningNight(), EVENT_CHANNEL_ID_EVENING_NIGHT);
|
||||
scheduleRange(thingUID, handler, sun.getDaylight(), EVENT_CHANNEL_ID_DAYLIGHT);
|
||||
|
||||
Eclipse eclipse = sun.getEclipse();
|
||||
eclipse.getKinds().forEach(eclipseKind -> {
|
||||
Calendar eclipseDate = eclipse.getDate(eclipseKind);
|
||||
if (eclipseDate != null) {
|
||||
scheduleEvent(thingUID, handler, eclipseDate, eclipseKind.toString(), EVENT_CHANNEL_ID_ECLIPSE, false);
|
||||
try {
|
||||
handler.publishDailyInfo();
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Scheduled Astro event-jobs for thing {}", handler.getThing().getUID());
|
||||
}
|
||||
});
|
||||
|
||||
// schedule republish jobs
|
||||
schedulePublishPlanet(thingUID, handler, sun.getZodiac().getEnd());
|
||||
schedulePublishPlanet(thingUID, handler, sun.getSeason().getNextSeason());
|
||||
Planet planet = handler.getPlanet();
|
||||
if (planet == null) {
|
||||
logger.error("Planet not instantiated");
|
||||
return;
|
||||
}
|
||||
Sun sun = (Sun) planet;
|
||||
scheduleRange(handler, sun.getRise(), EVENT_CHANNEL_ID_RISE, zone, locale);
|
||||
scheduleRange(handler, sun.getSet(), EVENT_CHANNEL_ID_SET, zone, locale);
|
||||
Range range = sun.getNoon();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NOON, zone, locale);
|
||||
}
|
||||
range = sun.getNight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NIGHT, zone, locale);
|
||||
}
|
||||
range = sun.getMorningNight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_MORNING_NIGHT, zone, locale);
|
||||
}
|
||||
range = sun.getAstroDawn();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_ASTRO_DAWN, zone, locale);
|
||||
}
|
||||
range = sun.getNauticDawn();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NAUTIC_DAWN, zone, locale);
|
||||
}
|
||||
range = sun.getCivilDawn();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_CIVIL_DAWN, zone, locale);
|
||||
}
|
||||
range = sun.getAstroDusk();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_ASTRO_DUSK, zone, locale);
|
||||
}
|
||||
range = sun.getNauticDusk();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NAUTIC_DUSK, zone, locale);
|
||||
}
|
||||
range = sun.getCivilDusk();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_CIVIL_DUSK, zone, locale);
|
||||
}
|
||||
range = sun.getEveningNight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_EVENING_NIGHT, zone, locale);
|
||||
}
|
||||
range = sun.getDaylight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_DAYLIGHT, zone, locale);
|
||||
}
|
||||
|
||||
// schedule phase jobs
|
||||
scheduleSunPhase(thingUID, handler, SUN_RISE, sun.getRise().getStart());
|
||||
scheduleSunPhase(thingUID, handler, SUN_SET, sun.getSet().getStart());
|
||||
scheduleSunPhase(thingUID, handler, NIGHT, sun.getNight().getStart());
|
||||
scheduleSunPhase(thingUID, handler, DAYLIGHT, sun.getDaylight().getStart());
|
||||
scheduleSunPhase(thingUID, handler, ASTRO_DAWN, sun.getAstroDawn().getStart());
|
||||
scheduleSunPhase(thingUID, handler, NAUTIC_DAWN, sun.getNauticDawn().getStart());
|
||||
scheduleSunPhase(thingUID, handler, CIVIL_DAWN, sun.getCivilDawn().getStart());
|
||||
scheduleSunPhase(thingUID, handler, ASTRO_DUSK, sun.getAstroDusk().getStart());
|
||||
scheduleSunPhase(thingUID, handler, NAUTIC_DUSK, sun.getNauticDusk().getStart());
|
||||
scheduleSunPhase(thingUID, handler, CIVIL_DUSK, sun.getCivilDusk().getStart());
|
||||
Eclipse eclipse = sun.getEclipse();
|
||||
eclipse.getKinds().forEach(eclipseKind -> {
|
||||
Calendar eclipseDate = eclipse.getDate(eclipseKind);
|
||||
if (eclipseDate != null) {
|
||||
scheduleEvent(handler, eclipseDate, eclipseKind.toString(), EVENT_CHANNEL_ID_ECLIPSE, false, zone,
|
||||
locale);
|
||||
}
|
||||
});
|
||||
|
||||
// schedule republish jobs
|
||||
SunZodiac sunZodiac;
|
||||
Calendar cal = (sunZodiac = sun.getZodiac()) == null ? null : sunZodiac.getEnd();
|
||||
if (cal != null) {
|
||||
schedulePublishPlanet(handler, cal, zone, locale);
|
||||
}
|
||||
schedulePublishPlanet(handler, sun.getSeason().getNextSeason(zone, locale), zone, locale);
|
||||
|
||||
// schedule phase jobs
|
||||
cal = sun.getRise().getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, SUN_RISE, cal, zone, locale);
|
||||
}
|
||||
cal = sun.getSet().getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, SUN_SET, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getNight()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, NIGHT, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getDaylight()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, DAYLIGHT, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getAstroDawn()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, ASTRO_DAWN, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getNauticDawn()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, NAUTIC_DAWN, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getCivilDawn()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, CIVIL_DAWN, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getAstroDusk()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, ASTRO_DUSK, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getNauticDusk()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, NAUTIC_DUSK, cal, zone, locale);
|
||||
}
|
||||
cal = (range = sun.getCivilDusk()) == null ? null : range.getStart();
|
||||
if (cal != null) {
|
||||
scheduleSunPhase(handler, CIVIL_DUSK, cal, zone, locale);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
logger.warn("The daily sun job execution for \"{}\" failed: {}", handler.getThing().getUID(),
|
||||
e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Daily job sun " + getThingUID();
|
||||
return "Daily job sun " + handler.getThing().getUID();
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.astro.internal.job;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.AstroHandlerFactory;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
|
||||
/**
|
||||
@@ -31,30 +30,31 @@ public final class EventJob extends AbstractJob {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thingUID thing UID
|
||||
* @param handler the thing handler
|
||||
* @param channelID channel ID
|
||||
* @param event Event name
|
||||
* @throws IllegalArgumentException
|
||||
* if any of the arguments is {@code null}
|
||||
*/
|
||||
public EventJob(String thingUID, String channelID, String event) {
|
||||
super(thingUID);
|
||||
public EventJob(AstroThingHandler handler, String channelID, String event) {
|
||||
super(handler);
|
||||
this.channelID = channelID;
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AstroThingHandler astroHandler = AstroHandlerFactory.getHandler(getThingUID());
|
||||
if (astroHandler != null) {
|
||||
astroHandler.triggerEvent(channelID, event);
|
||||
} else {
|
||||
LOGGER.trace("AstroThingHandler is null");
|
||||
try {
|
||||
handler.triggerEvent(channelID, event);
|
||||
} catch (Exception e) {
|
||||
logger.warn("The triggering of event \"{}\" for \"{}\" failed: {}", event, handler.getThing().getUID(),
|
||||
e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Event job " + getThingUID() + "/" + channelID + "/" + event;
|
||||
return "Event job " + handler.getThing().getUID() + "/" + channelID + "/" + event;
|
||||
}
|
||||
}
|
||||
|
||||
+34
-37
@@ -19,6 +19,8 @@ import static org.openhab.binding.astro.internal.util.DateTimeUtils.*;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.config.AstroChannelConfig;
|
||||
@@ -38,53 +40,50 @@ import org.slf4j.LoggerFactory;
|
||||
@NonNullByDefault
|
||||
public interface Job extends SchedulerRunnable, Runnable {
|
||||
|
||||
/** Logger Instance */
|
||||
final Logger LOGGER = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
/** The {@link Logger} Instance */
|
||||
final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
|
||||
|
||||
/**
|
||||
* Schedules the provided {@link Job} instance
|
||||
*
|
||||
* @param thingUID the UID of the Thing instance
|
||||
* @param astroHandler the {@link AstroThingHandler} instance
|
||||
* @param job the {@link Job} instance to schedule
|
||||
* @param eventAt the {@link Calendar} instance denoting scheduled instant
|
||||
*/
|
||||
static void schedule(String thingUID, AstroThingHandler astroHandler, Job job, Calendar eventAt) {
|
||||
static void schedule(AstroThingHandler astroHandler, Job job, Calendar eventAt, TimeZone zone, Locale locale) {
|
||||
try {
|
||||
Calendar today = Calendar.getInstance();
|
||||
Calendar today = Calendar.getInstance(zone, locale);
|
||||
if (isSameDay(eventAt, today) && isTimeGreaterEquals(eventAt, today)) {
|
||||
astroHandler.schedule(job, eventAt);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
LOGGER.error("{}", ex.getMessage(), ex);
|
||||
logger.error("{}", ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules an {@link EventJob} instance
|
||||
*
|
||||
* @param thingUID the Thing UID
|
||||
* @param astroHandler the {@link AstroThingHandler} instance
|
||||
* @param eventAt the {@link Calendar} instance denoting scheduled instant
|
||||
* @param event the event ID
|
||||
* @param channelId the channel ID
|
||||
*/
|
||||
static void scheduleEvent(String thingUID, AstroThingHandler astroHandler, Calendar eventAt, String event,
|
||||
String channelId, boolean configAlreadyApplied) {
|
||||
scheduleEvent(thingUID, astroHandler, eventAt, List.of(event), channelId, configAlreadyApplied);
|
||||
static void scheduleEvent(AstroThingHandler astroHandler, Calendar eventAt, String event, String channelId,
|
||||
boolean configAlreadyApplied, TimeZone zone, Locale locale) {
|
||||
scheduleEvent(astroHandler, eventAt, List.of(event), channelId, configAlreadyApplied, zone, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules an {@link EventJob} instance
|
||||
*
|
||||
* @param thingUID the Thing UID
|
||||
* @param astroHandler the {@link AstroThingHandler} instance
|
||||
* @param eventAt the {@link Calendar} instance denoting scheduled instant
|
||||
* @param events the event IDs to schedule
|
||||
* @param channelId the channel ID
|
||||
*/
|
||||
static void scheduleEvent(String thingUID, AstroThingHandler astroHandler, Calendar eventAt, List<String> events,
|
||||
String channelId, boolean configAlreadyApplied) {
|
||||
static void scheduleEvent(AstroThingHandler astroHandler, Calendar eventAt, List<String> events, String channelId,
|
||||
boolean configAlreadyApplied, TimeZone zone, Locale locale) {
|
||||
if (events.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
@@ -92,7 +91,7 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||
if (!configAlreadyApplied) {
|
||||
final Channel channel = astroHandler.getThing().getChannel(channelId);
|
||||
if (channel == null) {
|
||||
LOGGER.warn("Cannot find channel '{}' for thing '{}'.", channelId, astroHandler.getThing().getUID());
|
||||
logger.warn("Cannot find channel '{}' for thing '{}'.", channelId, astroHandler.getThing().getUID());
|
||||
return;
|
||||
}
|
||||
AstroChannelConfig config = channel.getConfiguration().as(AstroChannelConfig.class);
|
||||
@@ -100,48 +99,48 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||
} else {
|
||||
instant = eventAt;
|
||||
}
|
||||
List<Job> jobs = events.stream().map(e -> new EventJob(thingUID, channelId, e)).collect(toList());
|
||||
schedule(thingUID, astroHandler, new CompositeJob(thingUID, jobs), instant);
|
||||
List<Job> jobs = events.stream().map(e -> new EventJob(astroHandler, channelId, e)).collect(toList());
|
||||
schedule(astroHandler, new CompositeJob(astroHandler, jobs), instant, zone, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules {@link Channel} events
|
||||
*
|
||||
* @param thingUID the Thing UID
|
||||
* @param astroHandler the {@link AstroThingHandler} instance
|
||||
* @param range the {@link Range} instance
|
||||
* @param channelId the channel ID
|
||||
*/
|
||||
static void scheduleRange(String thingUID, AstroThingHandler astroHandler, Range range, String channelId) {
|
||||
static void scheduleRange(AstroThingHandler astroHandler, Range range, String channelId, TimeZone zone,
|
||||
Locale locale) {
|
||||
final Channel channel = astroHandler.getThing().getChannel(channelId);
|
||||
if (channel == null) {
|
||||
LOGGER.warn("Cannot find channel '{}' for thing '{}'.", channelId, astroHandler.getThing().getUID());
|
||||
logger.warn("Cannot find channel '{}' for thing '{}'.", channelId, astroHandler.getThing().getUID());
|
||||
return;
|
||||
}
|
||||
AstroChannelConfig config = channel.getConfiguration().as(AstroChannelConfig.class);
|
||||
Range adjustedRange = adjustRangeToConfig(range, config);
|
||||
Range adjustedRange = adjustRangeToConfig(range, config, zone, locale);
|
||||
|
||||
Calendar start = adjustedRange.getStart();
|
||||
Calendar end = adjustedRange.getEnd();
|
||||
|
||||
if (start == null || end == null) {
|
||||
LOGGER.debug("event was not scheduled as either start or end was null");
|
||||
logger.debug("event was not scheduled as either start or end was null");
|
||||
return;
|
||||
}
|
||||
|
||||
scheduleEvent(thingUID, astroHandler, start, EVENT_START, channelId, true);
|
||||
scheduleEvent(thingUID, astroHandler, end, EVENT_END, channelId, true);
|
||||
scheduleEvent(astroHandler, start, EVENT_START, channelId, true, zone, locale);
|
||||
scheduleEvent(astroHandler, end, EVENT_END, channelId, true, zone, locale);
|
||||
}
|
||||
|
||||
static Range adjustRangeToConfig(Range range, AstroChannelConfig config) {
|
||||
static Range adjustRangeToConfig(Range range, AstroChannelConfig config, TimeZone zone, Locale locale) {
|
||||
Calendar start = range.getStart();
|
||||
Calendar end = range.getEnd();
|
||||
|
||||
if (config.forceEvent && start == null) {
|
||||
start = getAdjustedEarliest(Calendar.getInstance(), config);
|
||||
start = getAdjustedEarliest(Calendar.getInstance(zone, locale), config);
|
||||
}
|
||||
if (config.forceEvent && end == null) {
|
||||
end = getAdjustedLatest(Calendar.getInstance(), config);
|
||||
end = getAdjustedLatest(Calendar.getInstance(zone, locale), config);
|
||||
}
|
||||
|
||||
// depending on the location and configuration you might not have a valid range for day/night, so skip the
|
||||
@@ -156,31 +155,29 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||
/**
|
||||
* Schedules Planet events
|
||||
*
|
||||
* @param thingUID the Thing UID
|
||||
* @param astroHandler the {@link AstroThingHandler} instance
|
||||
* @param eventAt the {@link Calendar} instance denoting scheduled instant
|
||||
*/
|
||||
static void schedulePublishPlanet(String thingUID, AstroThingHandler astroHandler, Calendar eventAt) {
|
||||
Job publishJob = new PublishPlanetJob(thingUID);
|
||||
schedule(thingUID, astroHandler, publishJob, eventAt);
|
||||
static void schedulePublishPlanet(AstroThingHandler astroHandler, Calendar eventAt, TimeZone zone, Locale locale) {
|
||||
Job publishJob = new PublishPlanetJob(astroHandler);
|
||||
schedule(astroHandler, publishJob, eventAt, zone, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules {@link SunPhaseJob}
|
||||
*
|
||||
* @param thingUID the Thing UID
|
||||
* @param astroHandler the {@link AstroThingHandler} instance
|
||||
* @param sunPhaseName {@link SunPhaseName} instance
|
||||
* @param eventAt the {@link Calendar} instance denoting scheduled instant
|
||||
*/
|
||||
static void scheduleSunPhase(String thingUID, AstroThingHandler astroHandler, SunPhaseName sunPhaseName,
|
||||
Calendar eventAt) {
|
||||
Job sunPhaseJob = new SunPhaseJob(thingUID, sunPhaseName);
|
||||
schedule(thingUID, astroHandler, sunPhaseJob, eventAt);
|
||||
static void scheduleSunPhase(AstroThingHandler astroHandler, SunPhaseName sunPhaseName, Calendar eventAt,
|
||||
TimeZone zone, Locale locale) {
|
||||
Job sunPhaseJob = new SunPhaseJob(astroHandler, sunPhaseName);
|
||||
schedule(astroHandler, sunPhaseJob, eventAt, zone, locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the thing UID that is associated with this {@link Job} (cannot be {@code null})
|
||||
* @return The {@link AstroThingHandler} associated with this {@link Job}.
|
||||
*/
|
||||
String getThingUID();
|
||||
AstroThingHandler getHandler();
|
||||
}
|
||||
|
||||
+10
-10
@@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.astro.internal.job;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.AstroHandlerFactory;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
|
||||
/**
|
||||
@@ -28,26 +27,27 @@ public final class PositionalJob extends AbstractJob {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thingUID thing UID
|
||||
* @param handler the thing handler
|
||||
* @throws IllegalArgumentException
|
||||
* if the provided argument is {@code null}
|
||||
*/
|
||||
public PositionalJob(String thingUID) {
|
||||
super(thingUID);
|
||||
public PositionalJob(AstroThingHandler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AstroThingHandler astroHandler = AstroHandlerFactory.getHandler(getThingUID());
|
||||
if (astroHandler != null) {
|
||||
astroHandler.publishPositionalInfo();
|
||||
} else {
|
||||
LOGGER.trace("AstroThingHandler is null");
|
||||
try {
|
||||
handler.publishPositionalInfo();
|
||||
} catch (Exception e) {
|
||||
logger.warn("The publishing of positional info for \"{}\" failed: {}", handler.getThing().getUID(),
|
||||
e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Positional job " + getThingUID();
|
||||
return "Positional job " + handler.getThing().getUID();
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -13,7 +13,6 @@
|
||||
package org.openhab.binding.astro.internal.job;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.AstroHandlerFactory;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
|
||||
/**
|
||||
@@ -28,26 +27,27 @@ public final class PublishPlanetJob extends AbstractJob {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thingUID thing UID
|
||||
* @param handler the thing handler
|
||||
* @throws IllegalArgumentException
|
||||
* if the provided argument is {@code null}
|
||||
*/
|
||||
public PublishPlanetJob(String thingUID) {
|
||||
super(thingUID);
|
||||
public PublishPlanetJob(AstroThingHandler handler) {
|
||||
super(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AstroThingHandler astroHandler = AstroHandlerFactory.getHandler(getThingUID());
|
||||
if (astroHandler != null) {
|
||||
astroHandler.publishDailyInfo();
|
||||
} else {
|
||||
LOGGER.trace("AstroThingHandler is null");
|
||||
try {
|
||||
handler.publishDailyInfo();
|
||||
} catch (Exception e) {
|
||||
logger.warn("The publishing of daily info for \"{}\" failed: {}", handler.getThing().getUID(),
|
||||
e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Publish planet job " + getThingUID();
|
||||
return "Publish planet job " + handler.getThing().getUID();
|
||||
}
|
||||
}
|
||||
|
||||
+13
-15
@@ -15,9 +15,7 @@ package org.openhab.binding.astro.internal.job;
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.CHANNEL_ID_SUN_PHASE_NAME;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.AstroHandlerFactory;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
import org.openhab.binding.astro.internal.model.Planet;
|
||||
import org.openhab.binding.astro.internal.model.Sun;
|
||||
import org.openhab.binding.astro.internal.model.SunPhaseName;
|
||||
import org.openhab.core.thing.Channel;
|
||||
@@ -36,37 +34,37 @@ public final class SunPhaseJob extends AbstractJob {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param thingUID thing UID
|
||||
* @param handler the thing handler
|
||||
* @param sunPhaseName {@link SunPhaseName} name
|
||||
* @throws IllegalArgumentException
|
||||
* if any of the arguments is {@code null}
|
||||
*/
|
||||
public SunPhaseJob(String thingUID, SunPhaseName sunPhaseName) {
|
||||
super(thingUID);
|
||||
public SunPhaseJob(AstroThingHandler handler, SunPhaseName sunPhaseName) {
|
||||
super(handler);
|
||||
this.sunPhaseName = sunPhaseName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AstroThingHandler astroHandler = AstroHandlerFactory.getHandler(getThingUID());
|
||||
if (astroHandler != null) {
|
||||
Channel phaseNameChannel = astroHandler.getThing().getChannel(CHANNEL_ID_SUN_PHASE_NAME);
|
||||
try {
|
||||
Channel phaseNameChannel = handler.getThing().getChannel(CHANNEL_ID_SUN_PHASE_NAME);
|
||||
if (phaseNameChannel != null) {
|
||||
Planet planet = astroHandler.getPlanet();
|
||||
if (planet instanceof Sun theSun) {
|
||||
if (handler.getPlanet() instanceof Sun theSun) {
|
||||
theSun.getPhase().setName(sunPhaseName);
|
||||
astroHandler.publishChannelIfLinked(phaseNameChannel.getUID());
|
||||
handler.publishChannelIfLinked(phaseNameChannel.getUID());
|
||||
}
|
||||
} else {
|
||||
LOGGER.trace("{}", "Phase Name Channel is null");
|
||||
logger.trace("Phase Name Channel for {} is null", handler.getThing().getUID());
|
||||
}
|
||||
} else {
|
||||
LOGGER.trace("AstroThingHandler is null");
|
||||
} catch (Exception e) {
|
||||
logger.warn("The publishing of the sun phase for \"{}\" failed: {}", handler.getThing().getUID(),
|
||||
e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Sun phase job " + getThingUID() + "/" + sunPhaseName;
|
||||
return "Sun phase job " + handler.getThing().getUID() + "/" + sunPhaseName;
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -12,11 +12,14 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Holds the calculated moon data.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Moon extends RiseSet implements Planet {
|
||||
private MoonPhase phase = new MoonPhase();
|
||||
private MoonDistance apogee = new MoonDistance();
|
||||
|
||||
+6
-2
@@ -19,6 +19,8 @@ import java.util.Calendar;
|
||||
|
||||
import javax.measure.quantity.Length;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
|
||||
/**
|
||||
@@ -27,14 +29,16 @@ import org.openhab.core.library.types.QuantityType;
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
* @author Christoph Weitkamp - Introduced UoM
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MoonDistance {
|
||||
|
||||
private Calendar date;
|
||||
private @Nullable Calendar date;
|
||||
private double distance;
|
||||
|
||||
/**
|
||||
* Returns the date of the calculated distance.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getDate() {
|
||||
return date;
|
||||
}
|
||||
@@ -42,7 +46,7 @@ public class MoonDistance {
|
||||
/**
|
||||
* Sets the date of the calculated distance.
|
||||
*/
|
||||
public void setDate(Calendar date) {
|
||||
public void setDate(@Nullable Calendar date) {
|
||||
this.date = date;
|
||||
}
|
||||
|
||||
|
||||
+18
-10
@@ -18,6 +18,8 @@ import javax.measure.quantity.Angle;
|
||||
import javax.measure.quantity.Dimensionless;
|
||||
import javax.measure.quantity.Time;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
|
||||
@@ -27,21 +29,23 @@ import org.openhab.core.library.unit.Units;
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
* @author Christoph Weitkamp - Introduced UoM
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MoonPhase {
|
||||
private Calendar firstQuarter;
|
||||
private Calendar full;
|
||||
private Calendar thirdQuarter;
|
||||
private Calendar newCalendar;
|
||||
private @Nullable Calendar firstQuarter;
|
||||
private @Nullable Calendar full;
|
||||
private @Nullable Calendar thirdQuarter;
|
||||
private @Nullable Calendar newCalendar;
|
||||
private double age;
|
||||
private double illumination;
|
||||
private double agePercent;
|
||||
private double ageDegree;
|
||||
|
||||
private MoonPhaseName name;
|
||||
private @Nullable MoonPhaseName name;
|
||||
|
||||
/**
|
||||
* Returns the date at which the moon is in the first quarter.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getFirstQuarter() {
|
||||
return firstQuarter;
|
||||
}
|
||||
@@ -49,13 +53,14 @@ public class MoonPhase {
|
||||
/**
|
||||
* Sets the date at which the moon is in the first quarter.
|
||||
*/
|
||||
public void setFirstQuarter(Calendar firstQuarter) {
|
||||
public void setFirstQuarter(@Nullable Calendar firstQuarter) {
|
||||
this.firstQuarter = firstQuarter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date of the full moon.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getFull() {
|
||||
return full;
|
||||
}
|
||||
@@ -63,13 +68,14 @@ public class MoonPhase {
|
||||
/**
|
||||
* Sets the date of the full moon.
|
||||
*/
|
||||
public void setFull(Calendar full) {
|
||||
public void setFull(@Nullable Calendar full) {
|
||||
this.full = full;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date at which the moon is in the third quarter.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getThirdQuarter() {
|
||||
return thirdQuarter;
|
||||
}
|
||||
@@ -77,13 +83,14 @@ public class MoonPhase {
|
||||
/**
|
||||
* Sets the date at which the moon is in the third quarter.
|
||||
*/
|
||||
public void setThirdQuarter(Calendar thirdQuarter) {
|
||||
public void setThirdQuarter(@Nullable Calendar thirdQuarter) {
|
||||
this.thirdQuarter = thirdQuarter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date of the new moon.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getNew() {
|
||||
return newCalendar;
|
||||
}
|
||||
@@ -91,7 +98,7 @@ public class MoonPhase {
|
||||
/**
|
||||
* Sets the date of the new moon.
|
||||
*/
|
||||
public void setNew(Calendar newCalendar) {
|
||||
public void setNew(@Nullable Calendar newCalendar) {
|
||||
this.newCalendar = newCalendar;
|
||||
}
|
||||
|
||||
@@ -126,6 +133,7 @@ public class MoonPhase {
|
||||
/**
|
||||
* Returns the phase name.
|
||||
*/
|
||||
@Nullable
|
||||
public MoonPhaseName getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -133,7 +141,7 @@ public class MoonPhase {
|
||||
/**
|
||||
* Sets the phase name.
|
||||
*/
|
||||
public void setName(MoonPhaseName name) {
|
||||
public void setName(@Nullable MoonPhaseName name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -12,11 +12,14 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* All moon phases.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum MoonPhaseName {
|
||||
NEW,
|
||||
WAXING_CRESCENT,
|
||||
|
||||
+4
-1
@@ -12,10 +12,13 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Marker interface for all planets.
|
||||
*
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public interface Planet {
|
||||
}
|
||||
|
||||
+2
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.dimension.Intensity;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
@@ -22,6 +23,7 @@ import org.openhab.core.library.unit.Units;
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
* @author Christoph Weitkamp - Introduced UoM
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Radiation {
|
||||
|
||||
private double direct;
|
||||
|
||||
+17
-4
@@ -19,6 +19,8 @@ import java.util.Comparator;
|
||||
|
||||
import javax.measure.quantity.Time;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
@@ -29,15 +31,16 @@ import org.openhab.core.library.unit.Units;
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
* @author Christoph Weitkamp - Introduced UoM
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Range {
|
||||
|
||||
private Calendar start;
|
||||
private Calendar end;
|
||||
private @Nullable Calendar start;
|
||||
private @Nullable Calendar end;
|
||||
|
||||
public Range() {
|
||||
}
|
||||
|
||||
public Range(Calendar start, Calendar end) {
|
||||
public Range(@Nullable Calendar start, @Nullable Calendar end) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
}
|
||||
@@ -45,6 +48,7 @@ public class Range {
|
||||
/**
|
||||
* Returns the start of the range.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getStart() {
|
||||
return start;
|
||||
}
|
||||
@@ -52,6 +56,7 @@ public class Range {
|
||||
/**
|
||||
* Returns the end of the range.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getEnd() {
|
||||
return end;
|
||||
}
|
||||
@@ -59,7 +64,10 @@ public class Range {
|
||||
/**
|
||||
* Returns the duration in minutes.
|
||||
*/
|
||||
@Nullable
|
||||
public QuantityType<Time> getDuration() {
|
||||
Calendar start = this.start;
|
||||
Calendar end = this.end;
|
||||
if (start == null || end == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -83,7 +91,12 @@ public class Range {
|
||||
return cal.getTimeInMillis() >= matchStart && cal.getTimeInMillis() < matchEnd;
|
||||
}
|
||||
|
||||
private static Comparator<Calendar> nullSafeCalendarComparator = Comparator.nullsFirst(Calendar::compareTo);
|
||||
private static Comparator<@Nullable Calendar> nullSafeCalendarComparator = (c1, c2) -> {
|
||||
if (c1 == null) {
|
||||
return (c2 == null) ? 0 : -1;
|
||||
}
|
||||
return c2 == null ? 1 : c1.compareTo(c2);
|
||||
};
|
||||
|
||||
private static Comparator<Range> rangeComparator = Comparator.comparing(Range::getStart, nullSafeCalendarComparator)
|
||||
.thenComparing(Range::getEnd, nullSafeCalendarComparator);
|
||||
|
||||
+26
-16
@@ -15,9 +15,13 @@ package org.openhab.binding.astro.internal.model;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.measure.quantity.Time;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
@@ -27,17 +31,19 @@ import org.openhab.core.library.unit.Units;
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Season {
|
||||
private Calendar spring;
|
||||
private Calendar summer;
|
||||
private Calendar autumn;
|
||||
private Calendar winter;
|
||||
private @Nullable Calendar spring;
|
||||
private @Nullable Calendar summer;
|
||||
private @Nullable Calendar autumn;
|
||||
private @Nullable Calendar winter;
|
||||
|
||||
private SeasonName name;
|
||||
private @Nullable SeasonName name;
|
||||
|
||||
/**
|
||||
* Returns the date of the beginning of spring.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getSpring() {
|
||||
return spring;
|
||||
}
|
||||
@@ -45,13 +51,14 @@ public class Season {
|
||||
/**
|
||||
* Sets the date of the beginning of spring.
|
||||
*/
|
||||
public void setSpring(Calendar spring) {
|
||||
public void setSpring(@Nullable Calendar spring) {
|
||||
this.spring = spring;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date of the beginning of summer.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getSummer() {
|
||||
return summer;
|
||||
}
|
||||
@@ -59,13 +66,14 @@ public class Season {
|
||||
/**
|
||||
* Sets the date of the beginning of summer.
|
||||
*/
|
||||
public void setSummer(Calendar summer) {
|
||||
public void setSummer(@Nullable Calendar summer) {
|
||||
this.summer = summer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date of the beginning of autumn.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getAutumn() {
|
||||
return autumn;
|
||||
}
|
||||
@@ -73,13 +81,14 @@ public class Season {
|
||||
/**
|
||||
* Sets the date of the beginning of autumn.
|
||||
*/
|
||||
public void setAutumn(Calendar autumn) {
|
||||
public void setAutumn(@Nullable Calendar autumn) {
|
||||
this.autumn = autumn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the date of the beginning of winter.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getWinter() {
|
||||
return winter;
|
||||
}
|
||||
@@ -87,13 +96,14 @@ public class Season {
|
||||
/**
|
||||
* Returns the date of the beginning of winter.
|
||||
*/
|
||||
public void setWinter(Calendar winter) {
|
||||
public void setWinter(@Nullable Calendar winter) {
|
||||
this.winter = winter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current season name.
|
||||
*/
|
||||
@Nullable
|
||||
public SeasonName getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -101,22 +111,22 @@ public class Season {
|
||||
/**
|
||||
* Sets the current season name.
|
||||
*/
|
||||
public void setName(SeasonName name) {
|
||||
public void setName(@Nullable SeasonName name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next season.
|
||||
*/
|
||||
public Calendar getNextSeason() {
|
||||
return DateTimeUtils.getNextFromToday(spring, summer, autumn, winter);
|
||||
public Calendar getNextSeason(TimeZone zone, Locale locale) {
|
||||
return DateTimeUtils.getNextFromToday(zone, locale, spring, summer, autumn, winter);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next season name.
|
||||
*/
|
||||
public SeasonName getNextName() {
|
||||
int ordinal = name.ordinal() + 1;
|
||||
int ordinal = name == null ? 0 : name.ordinal() + 1;
|
||||
if (ordinal > 3) {
|
||||
ordinal = 0;
|
||||
}
|
||||
@@ -126,9 +136,9 @@ public class Season {
|
||||
/**
|
||||
* Returns the time left for current season
|
||||
*/
|
||||
public QuantityType<Time> getTimeLeft() {
|
||||
final Calendar now = Calendar.getInstance();
|
||||
final Calendar next = getNextSeason();
|
||||
public QuantityType<Time> getTimeLeft(TimeZone zone, Locale locale) {
|
||||
final Calendar now = Calendar.getInstance(zone, locale);
|
||||
final Calendar next = getNextSeason(zone, locale);
|
||||
final Duration timeLeft = Duration.of(next.getTimeInMillis() - now.getTimeInMillis(), ChronoUnit.MILLIS);
|
||||
|
||||
return new QuantityType<>(timeLeft.toDays(), Units.DAY);
|
||||
|
||||
+3
@@ -12,11 +12,14 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* All season names.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public enum SeasonName {
|
||||
SPRING,
|
||||
SUMMER,
|
||||
|
||||
+18
-2
@@ -15,18 +15,22 @@ package org.openhab.binding.astro.internal.model;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Holds the calculated sun data.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Sun extends RiseSet implements Planet {
|
||||
|
||||
private Map<SunPhaseName, Range> ranges = new HashMap<>();
|
||||
|
||||
private Position position = new Position();
|
||||
|
||||
private SunZodiac zodiac = new SunZodiac(null, null);
|
||||
private @Nullable SunZodiac zodiac;
|
||||
|
||||
private Season season = new Season();
|
||||
|
||||
@@ -39,6 +43,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the astro dawn range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getAstroDawn() {
|
||||
return ranges.get(SunPhaseName.ASTRO_DAWN);
|
||||
}
|
||||
@@ -53,6 +58,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the nautic dawn range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getNauticDawn() {
|
||||
return ranges.get(SunPhaseName.NAUTIC_DAWN);
|
||||
}
|
||||
@@ -67,6 +73,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the civil dawn range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getCivilDawn() {
|
||||
return ranges.get(SunPhaseName.CIVIL_DAWN);
|
||||
}
|
||||
@@ -81,6 +88,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the civil dusk range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getCivilDusk() {
|
||||
return ranges.get(SunPhaseName.CIVIL_DUSK);
|
||||
}
|
||||
@@ -95,6 +103,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the nautic dusk range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getNauticDusk() {
|
||||
return ranges.get(SunPhaseName.NAUTIC_DUSK);
|
||||
}
|
||||
@@ -109,6 +118,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the astro dusk range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getAstroDusk() {
|
||||
return ranges.get(SunPhaseName.ASTRO_DUSK);
|
||||
}
|
||||
@@ -123,6 +133,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the noon range, start and end is always equal.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getNoon() {
|
||||
return ranges.get(SunPhaseName.NOON);
|
||||
}
|
||||
@@ -137,6 +148,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the daylight range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getDaylight() {
|
||||
return ranges.get(SunPhaseName.DAYLIGHT);
|
||||
}
|
||||
@@ -151,6 +163,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the morning night range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getMorningNight() {
|
||||
return ranges.get(SunPhaseName.MORNING_NIGHT);
|
||||
}
|
||||
@@ -165,6 +178,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the evening night range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getEveningNight() {
|
||||
return ranges.get(SunPhaseName.EVENING_NIGHT);
|
||||
}
|
||||
@@ -179,6 +193,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the night range.
|
||||
*/
|
||||
@Nullable
|
||||
public Range getNight() {
|
||||
return ranges.get(SunPhaseName.NIGHT);
|
||||
}
|
||||
@@ -232,6 +247,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Returns the zodiac.
|
||||
*/
|
||||
@Nullable
|
||||
public SunZodiac getZodiac() {
|
||||
return zodiac;
|
||||
}
|
||||
@@ -239,7 +255,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
/**
|
||||
* Sets the zodiac.
|
||||
*/
|
||||
public void setZodiac(SunZodiac zodiac) {
|
||||
public void setZodiac(@Nullable SunZodiac zodiac) {
|
||||
this.zodiac = zodiac;
|
||||
}
|
||||
|
||||
|
||||
+7
-2
@@ -12,17 +12,22 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Holds the calculated sun phase informations.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SunPhase {
|
||||
private SunPhaseName name;
|
||||
private @Nullable SunPhaseName name;
|
||||
|
||||
/**
|
||||
* Returns the sun phase.
|
||||
*/
|
||||
@Nullable
|
||||
public SunPhaseName getName() {
|
||||
return name;
|
||||
}
|
||||
@@ -30,7 +35,7 @@ public class SunPhase {
|
||||
/**
|
||||
* Sets the sun phase.
|
||||
*/
|
||||
public void setName(SunPhaseName name) {
|
||||
public void setName(@Nullable SunPhaseName name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-5
@@ -14,11 +14,15 @@ package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Extends the zodiac with a date range.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class SunZodiac extends Zodiac {
|
||||
private Range range;
|
||||
|
||||
@@ -33,26 +37,30 @@ public class SunZodiac extends Zodiac {
|
||||
/**
|
||||
* Returns she start of the zodiac.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getStart() {
|
||||
return range == null ? null : range.getStart();
|
||||
return range.getStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end of the zodiac.
|
||||
*/
|
||||
@Nullable
|
||||
public Calendar getEnd() {
|
||||
return range == null ? null : range.getEnd();
|
||||
return range.getEnd();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true, if the zodiac is valid on the specified calendar object.
|
||||
*/
|
||||
public boolean isValid(Calendar calendar) {
|
||||
if (range == null || range.getStart() == null || range.getEnd() == null) {
|
||||
Calendar start = range.getStart();
|
||||
Calendar end = range.getEnd();
|
||||
if (start == null || end == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return range.getStart().getTimeInMillis() <= calendar.getTimeInMillis()
|
||||
&& range.getEnd().getTimeInMillis() >= calendar.getTimeInMillis();
|
||||
return start.getTimeInMillis() <= calendar.getTimeInMillis()
|
||||
&& end.getTimeInMillis() >= calendar.getTimeInMillis();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -12,21 +12,26 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Holds the sign of the zodiac.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Zodiac {
|
||||
private ZodiacSign sign;
|
||||
private @Nullable ZodiacSign sign;
|
||||
|
||||
public Zodiac(ZodiacSign sign) {
|
||||
public Zodiac(@Nullable ZodiacSign sign) {
|
||||
this.sign = sign;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sign of the zodiac.
|
||||
*/
|
||||
@Nullable
|
||||
public ZodiacSign getSign() {
|
||||
return sign;
|
||||
}
|
||||
|
||||
+37
-31
@@ -13,8 +13,12 @@
|
||||
package org.openhab.binding.astro.internal.util;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.config.AstroChannelConfig;
|
||||
import org.openhab.binding.astro.internal.model.Range;
|
||||
import org.slf4j.Logger;
|
||||
@@ -25,6 +29,7 @@ import org.slf4j.LoggerFactory;
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class DateTimeUtils {
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(DateTimeUtils.class);
|
||||
private static final Pattern HHMM_PATTERN = Pattern.compile("^([0-1][0-9]|2[0-3])(:[0-5][0-9])$");
|
||||
@@ -49,7 +54,7 @@ public class DateTimeUtils {
|
||||
/**
|
||||
* Truncates the time from the calendar object.
|
||||
*/
|
||||
private static Calendar truncateToMinute(Calendar calendar) {
|
||||
public static Calendar truncateToMinute(Calendar calendar) {
|
||||
Calendar cal = truncateToSecond(calendar);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
return cal;
|
||||
@@ -69,14 +74,15 @@ public class DateTimeUtils {
|
||||
* Creates a Range object within the specified months and days. The start
|
||||
* time is midnight, the end time is end of the day.
|
||||
*/
|
||||
public static Range getRange(int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay) {
|
||||
Calendar start = Calendar.getInstance();
|
||||
public static Range getRange(int startYear, int startMonth, int startDay, int endYear, int endMonth, int endDay,
|
||||
TimeZone zone, Locale locale) {
|
||||
Calendar end = Calendar.getInstance(zone, locale);
|
||||
Calendar start = (Calendar) end.clone();
|
||||
start.set(Calendar.YEAR, startYear);
|
||||
start.set(Calendar.MONTH, startMonth);
|
||||
start.set(Calendar.DAY_OF_MONTH, startDay);
|
||||
start = truncateToMidnight(start);
|
||||
|
||||
Calendar end = Calendar.getInstance();
|
||||
end.set(Calendar.YEAR, endYear);
|
||||
end.set(Calendar.MONTH, endMonth);
|
||||
end.set(Calendar.DAY_OF_MONTH, endDay);
|
||||
@@ -91,18 +97,15 @@ public class DateTimeUtils {
|
||||
/**
|
||||
* Returns a calendar object from a julian date.
|
||||
*/
|
||||
public static Calendar toCalendar(double julianDate) {
|
||||
@Nullable
|
||||
public static Calendar toCalendar(double julianDate, TimeZone zone, Locale locale) {
|
||||
if (Double.compare(julianDate, Double.NaN) == 0 || julianDate == 0) {
|
||||
return null;
|
||||
}
|
||||
long millis = (long) ((julianDate + 0.5 - J1970) * MILLISECONDS_PER_DAY);
|
||||
Calendar cal = Calendar.getInstance();
|
||||
Calendar cal = Calendar.getInstance(zone, locale);
|
||||
cal.setTimeInMillis(millis);
|
||||
int second = cal.get(Calendar.SECOND);
|
||||
if (second > 30) {
|
||||
cal.add(Calendar.MINUTE, 1);
|
||||
}
|
||||
return truncateToMinute(cal);
|
||||
return cal;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,6 +143,7 @@ public class DateTimeUtils {
|
||||
/**
|
||||
* Converts the time (hour.minute) to a calendar object.
|
||||
*/
|
||||
@Nullable
|
||||
public static Calendar timeToCalendar(Calendar calendar, double time) {
|
||||
if (time < 0.0) {
|
||||
return null;
|
||||
@@ -147,12 +151,13 @@ public class DateTimeUtils {
|
||||
Calendar cal = (Calendar) calendar.clone();
|
||||
int hour = 0;
|
||||
int minute = 0;
|
||||
if (time == 24.0) {
|
||||
cal.add(Calendar.DAY_OF_MONTH, 1);
|
||||
} else {
|
||||
hour = (int) time;
|
||||
minute = (int) ((time * 100) - (hour * 100));
|
||||
int days = (int) time / 24;
|
||||
double remains = time % 24;
|
||||
if (days != 0) {
|
||||
cal.add(Calendar.DAY_OF_MONTH, days);
|
||||
}
|
||||
hour = (int) remains;
|
||||
minute = (int) ((remains * 100) - (hour * 100));
|
||||
cal.set(Calendar.HOUR_OF_DAY, hour);
|
||||
cal.set(Calendar.MINUTE, minute);
|
||||
return truncateToMinute(cal);
|
||||
@@ -161,7 +166,7 @@ public class DateTimeUtils {
|
||||
/**
|
||||
* Returns true, if two calendar objects are on the same day ignoring time.
|
||||
*/
|
||||
public static boolean isSameDay(Calendar cal1, Calendar cal2) {
|
||||
public static boolean isSameDay(@Nullable Calendar cal1, @Nullable Calendar cal2) {
|
||||
return cal1 != null && cal2 != null && cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA)
|
||||
&& cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
|
||||
&& cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
|
||||
@@ -170,10 +175,13 @@ public class DateTimeUtils {
|
||||
/**
|
||||
* Returns the next Calendar from today.
|
||||
*/
|
||||
public static Calendar getNextFromToday(Calendar... calendars) {
|
||||
return getNext(Calendar.getInstance(), calendars);
|
||||
public static Calendar getNextFromToday(TimeZone zone, Locale locale, Calendar... calendars) {
|
||||
Calendar now = Calendar.getInstance(zone, locale);
|
||||
Calendar result = getNext(now, calendars);
|
||||
return result == null ? now : result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static Calendar getNext(Calendar now, Calendar... calendars) {
|
||||
Calendar next = null;
|
||||
Calendar firstSeasonOfYear = null;
|
||||
@@ -185,7 +193,7 @@ public class DateTimeUtils {
|
||||
next = calendar;
|
||||
}
|
||||
}
|
||||
if (next == null) {
|
||||
if (next == null && firstSeasonOfYear != null) {
|
||||
final Calendar nextYearSeason = (Calendar) firstSeasonOfYear.clone();
|
||||
|
||||
nextYearSeason.add(Calendar.YEAR, 1);
|
||||
@@ -205,11 +213,11 @@ public class DateTimeUtils {
|
||||
}
|
||||
|
||||
public static Calendar getAdjustedEarliest(Calendar cal, AstroChannelConfig config) {
|
||||
return adjustTime(cal, getMinutesFromTime(config.earliest));
|
||||
return config.earliest == null ? cal : adjustTime(cal, getMinutesFromTime(config.earliest));
|
||||
}
|
||||
|
||||
public static Calendar getAdjustedLatest(Calendar cal, AstroChannelConfig config) {
|
||||
return adjustTime(cal, getMinutesFromTime(config.latest));
|
||||
return config.latest == null ? cal : adjustTime(cal, getMinutesFromTime(config.latest));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,17 +226,15 @@ public class DateTimeUtils {
|
||||
public static Calendar applyConfig(Calendar cal, AstroChannelConfig config) {
|
||||
Calendar cCal = cal;
|
||||
if (config.offset != 0) {
|
||||
Calendar cOffset = Calendar.getInstance();
|
||||
cOffset.setTime(cCal.getTime());
|
||||
cOffset.add(Calendar.MINUTE, config.offset);
|
||||
cCal = cOffset;
|
||||
cCal = (Calendar) cal.clone();
|
||||
cCal.add(Calendar.MINUTE, config.offset);
|
||||
}
|
||||
|
||||
Calendar cEarliest = getAdjustedEarliest(cCal, config);
|
||||
Calendar cEarliest = getAdjustedEarliest(cal, config);
|
||||
if (cCal.before(cEarliest)) {
|
||||
return cEarliest;
|
||||
}
|
||||
Calendar cLatest = getAdjustedLatest(cCal, config);
|
||||
Calendar cLatest = getAdjustedLatest(cal, config);
|
||||
if (cCal.after(cLatest)) {
|
||||
return cLatest;
|
||||
}
|
||||
@@ -245,14 +251,14 @@ public class DateTimeUtils {
|
||||
return cal;
|
||||
}
|
||||
|
||||
public static Calendar createCalendarForToday(int hour, int minute) {
|
||||
return DateTimeUtils.adjustTime(Calendar.getInstance(), hour * 60 + minute);
|
||||
public static Calendar createCalendarForToday(int hour, int minute, TimeZone zone, Locale locale) {
|
||||
return DateTimeUtils.adjustTime(Calendar.getInstance(zone, locale), hour * 60 + minute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a HH:MM string and returns the minutes.
|
||||
*/
|
||||
private static int getMinutesFromTime(String configTime) {
|
||||
private static int getMinutesFromTime(@Nullable String configTime) {
|
||||
if (configTime != null) {
|
||||
String time = configTime.trim();
|
||||
if (!time.isEmpty()) {
|
||||
|
||||
+2
-3
@@ -15,7 +15,6 @@ package org.openhab.binding.astro.internal.util;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
@@ -52,7 +51,7 @@ public class PropertyUtils {
|
||||
/**
|
||||
* Returns the state of the channel.
|
||||
*/
|
||||
public static State getState(ChannelUID channelUID, AstroChannelConfig config, Object instance, ZoneId zoneId)
|
||||
public static State getState(ChannelUID channelUID, AstroChannelConfig config, Object instance, TimeZone zone)
|
||||
throws Exception {
|
||||
Object value = getPropertyValue(channelUID, instance);
|
||||
if (value == null) {
|
||||
@@ -61,7 +60,7 @@ public class PropertyUtils {
|
||||
return state;
|
||||
} else if (value instanceof Calendar cal) {
|
||||
GregorianCalendar gregorianCal = (GregorianCalendar) DateTimeUtils.applyConfig(cal, config);
|
||||
cal.setTimeZone(TimeZone.getTimeZone(zoneId));
|
||||
cal.setTimeZone(zone);
|
||||
ZonedDateTime zoned = gregorianCal.toZonedDateTime().withFixedOffsetZone();
|
||||
return new DateTimeType(zoned);
|
||||
} else if (value instanceof Number) {
|
||||
|
||||
+42
-24
@@ -16,12 +16,14 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.astro.internal.model.Moon;
|
||||
import org.openhab.binding.astro.internal.model.ZodiacSign;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
|
||||
/***
|
||||
* Specific unit tests to check if {@link MoonCalc} generates correct data for
|
||||
@@ -55,7 +57,7 @@ public class MoonCalcTest {
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForOldDate() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertNotNull(moon.getApogee());
|
||||
assertNotNull(moon.getPerigee());
|
||||
@@ -75,55 +77,63 @@ public class MoonCalcTest {
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForApogeeAccuracy() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// expected result from haevens-above.com is 406,391 km @ 04 March 2019 12:27
|
||||
assertEquals(406391, moon.getApogee().getDistance().doubleValue(), ACCURACY_IN_KILOMETRES);
|
||||
Calendar apogeeDate = moon.getApogee().getDate();
|
||||
assertNotNull(apogeeDate);
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 4, 12, 27, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getApogee().getDate().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
apogeeDate.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForPerigeeAccuracy() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// expected result from haevens-above.com is 359,377 km @ 19 February 2019 20:44
|
||||
assertEquals(359377, moon.getPerigee().getDistance().doubleValue(), ACCURACY_IN_KILOMETRES);
|
||||
|
||||
Calendar perigeeDate = moon.getPerigee().getDate();
|
||||
assertNotNull(perigeeDate);
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 19, 20, 48, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getPerigee().getDate().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
perigeeDate.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForRiseAccuracy() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Calendar riseStart = moon.getRise().getStart();
|
||||
assertNotNull(riseStart);
|
||||
// expected result from haevens-above.com is 03:00
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 3, 0, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getRise().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
riseStart.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForSetAccuracy() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Calendar setStart = moon.getSet().getStart();
|
||||
assertNotNull(setStart);
|
||||
// expected result from haevens-above.com is 11:35
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 11, 35, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getSet().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
setStart.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForZodiac() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(ZodiacSign.SAGITTARIUS, moon.getZodiac().getSign());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForMoonPositionAccuracy() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// expected result from haevens-above.com is Azimuth: 100.5, altitude -17
|
||||
assertEquals(100.5, moon.getPosition().getAzimuth().doubleValue(), ACCURACY_IN_DEGREE);
|
||||
@@ -132,8 +142,8 @@ public class MoonCalcTest {
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForMoonDistanceAccuracy() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// expected result from haevens-above.com is 392612 km
|
||||
assertEquals(392612, moon.getDistance().getDistance().doubleValue(), ACCURACY_IN_KILOMETRES);
|
||||
@@ -141,21 +151,29 @@ public class MoonCalcTest {
|
||||
|
||||
@Test
|
||||
public void testGetMoonInfoForMoonPhaseAccuracy() {
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon);
|
||||
Moon moon = moonCalc.getMoonInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, TIME_ZONE, Locale.ROOT);
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// New moon 06 March 2019 17:04
|
||||
// First quarter 14 March 2019 11:27
|
||||
// Full moon 21 March 2019 02:43
|
||||
// Last quarter 28 March 2019 05:10
|
||||
Calendar phaseCal = moon.getPhase().getNew();
|
||||
assertNotNull(phaseCal);
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 06, 17, 04, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getPhase().getNew().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
phaseCal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
phaseCal = moon.getPhase().getFirstQuarter();
|
||||
assertNotNull(phaseCal);
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 14, 11, 27, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getPhase().getFirstQuarter().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
phaseCal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
phaseCal = moon.getPhase().getFull();
|
||||
assertNotNull(phaseCal);
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 21, 02, 43, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getPhase().getFull().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
phaseCal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
phaseCal = moon.getPhase().getThirdQuarter();
|
||||
assertNotNull(phaseCal);
|
||||
assertEquals(MoonCalcTest.newCalendar(2019, Calendar.MARCH, 28, 05, 10, TIME_ZONE).getTimeInMillis(),
|
||||
moon.getPhase().getThirdQuarter().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
phaseCal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
/***
|
||||
@@ -182,9 +200,9 @@ public class MoonCalcTest {
|
||||
* @return
|
||||
*/
|
||||
private static Calendar newCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, TimeZone zone) {
|
||||
Calendar result = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute);
|
||||
result.setTimeZone(zone);
|
||||
Calendar result = new GregorianCalendar(zone, Locale.ROOT);
|
||||
result.set(year, month, dayOfMonth, hourOfDay, minute);
|
||||
|
||||
return result;
|
||||
return DateTimeUtils.truncateToMinute(result);
|
||||
}
|
||||
}
|
||||
|
||||
+187
-76
@@ -16,13 +16,16 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.astro.internal.model.Range;
|
||||
import org.openhab.binding.astro.internal.model.Sun;
|
||||
import org.openhab.binding.astro.internal.model.SunPhaseName;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
|
||||
/***
|
||||
* Specific unit tests to check if {@link SunCalc} generates correct data for
|
||||
@@ -58,7 +61,8 @@ public class SunCalcTest {
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForOldDate() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertNotNull(sun.getNight());
|
||||
|
||||
@@ -86,192 +90,297 @@ public class SunCalcTest {
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForAstronomicalDawnAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getAstroDawn();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 05:39 till 06:18
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 5, 39, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getAstroDawn().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal = range.getEnd();
|
||||
assertNotNull(cal);
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 6, 18, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getAstroDawn().getEnd().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForNauticDawnAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getNauticDawn();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 06:18 till 06:58
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 6, 18, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getNauticDawn().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal = range.getEnd();
|
||||
assertNotNull(cal);
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 6, 58, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getNauticDawn().getEnd().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForCivilDawnAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getCivilDawn();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 06:58 till 07:32
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 6, 58, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getCivilDawn().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal = range.getEnd();
|
||||
assertNotNull(cal);
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 7, 32, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getCivilDawn().getEnd().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForRiseAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getRise();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 07:32
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 7, 32, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getRise().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForSunNoonAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getNoon();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 12:54
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 12, 54, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getNoon().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForSetAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getSet();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 18:15
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 18, 15, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getSet().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForCivilDuskAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getCivilDusk();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 18:15 till 18:50
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 18, 15, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getCivilDusk().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal = range.getEnd();
|
||||
assertNotNull(cal);
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 18, 50, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getCivilDusk().getEnd().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForNauticDuskAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getNauticDusk();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 18:50 till 19:29
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 18, 50, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getNauticDusk().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal = range.getEnd();
|
||||
assertNotNull(cal);
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 19, 29, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getNauticDusk().getEnd().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSunInfoForAstronomicalDuskAccuracy() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
Range range = sun.getAstroDusk();
|
||||
assertNotNull(range);
|
||||
Calendar cal = range.getStart();
|
||||
assertNotNull(cal);
|
||||
// expected result from haevens-above.com is 27 Feb 2019 19:29 till 20:09
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 19, 29, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getAstroDusk().getStart().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal = range.getEnd();
|
||||
assertNotNull(cal);
|
||||
assertEquals(SunCalcTest.newCalendar(2019, Calendar.FEBRUARY, 27, 20, 9, TIME_ZONE).getTimeInMillis(),
|
||||
sun.getAstroDusk().getEnd().getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
cal.getTimeInMillis(), ACCURACY_IN_MILLIS);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled
|
||||
public void testRangesForCoherenceBetweenNightEndAndAstroDawnStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.NIGHT).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.ASTRO_DAWN).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.NIGHT);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.ASTRO_DAWN);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenMorningNightEndAndAstroDawnStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.MORNING_NIGHT).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.ASTRO_DAWN).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.MORNING_NIGHT);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.ASTRO_DAWN);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenAstroDownEndAndNauticDawnStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.ASTRO_DAWN).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.NAUTIC_DAWN).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.ASTRO_DAWN);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.NAUTIC_DAWN);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenNauticDawnEndAndCivilDawnStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.NAUTIC_DAWN).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.CIVIL_DAWN).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.NAUTIC_DAWN);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.CIVIL_DAWN);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenCivilDawnEndAndSunRiseStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.CIVIL_DAWN).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.SUN_RISE).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.CIVIL_DAWN);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.SUN_RISE);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenSunRiseEndAndDaylightStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.SUN_RISE).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.DAYLIGHT).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.SUN_RISE);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.DAYLIGHT);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenDaylightEndAndSunSetStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.DAYLIGHT).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.SUN_SET).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.DAYLIGHT);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.SUN_SET);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenSunSetEndAndCivilDuskStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.SUN_SET).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.CIVIL_DUSK).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.SUN_SET);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.CIVIL_DUSK);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenCivilDuskEndAndNauticDuskStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.CIVIL_DUSK).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.NAUTIC_DUSK).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.CIVIL_DUSK);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.NAUTIC_DUSK);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenNauticDuskEndAndAstroDuskStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.NAUTIC_DUSK).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.ASTRO_DUSK).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.NAUTIC_DUSK);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.ASTRO_DUSK);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenAstroDuskEndAndNightStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.ASTRO_DUSK).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.NIGHT).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.ASTRO_DUSK);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.NIGHT);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRangesForCoherenceBetweenAstroDuskEndAndEveningNightStart() {
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false);
|
||||
Sun sun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE, false,
|
||||
TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(sun.getAllRanges().get(SunPhaseName.ASTRO_DUSK).getEnd(),
|
||||
sun.getAllRanges().get(SunPhaseName.EVENING_NIGHT).getStart());
|
||||
Range range = sun.getAllRanges().get(SunPhaseName.ASTRO_DUSK);
|
||||
assertNotNull(range);
|
||||
Range range2 = sun.getAllRanges().get(SunPhaseName.EVENING_NIGHT);
|
||||
assertNotNull(range2);
|
||||
assertEquals(range.getEnd(), range2.getStart());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -279,7 +388,7 @@ public class SunCalcTest {
|
||||
TimeZone tZone = TimeZone.getTimeZone("Europe/London");
|
||||
Calendar tDate = SunCalcTest.newCalendar(2020, Calendar.MAY, 13, 5, 12, tZone);
|
||||
|
||||
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true);
|
||||
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true, TIME_ZONE, Locale.ROOT);
|
||||
assertEquals(SunPhaseName.CIVIL_DAWN, sun.getPhase().getName());
|
||||
}
|
||||
|
||||
@@ -288,8 +397,9 @@ public class SunCalcTest {
|
||||
// SunCalc.ranges was not sorted, causing unexpected output in corner cases.
|
||||
TimeZone tZone = TimeZone.getTimeZone("Europe/London");
|
||||
Calendar tDate = SunCalcTest.newCalendar(2020, Calendar.MAY, 13, 5, 13, tZone);
|
||||
tDate.set(Calendar.SECOND, 4);
|
||||
|
||||
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true);
|
||||
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true, TIME_ZONE, Locale.ROOT);
|
||||
assertEquals(SunPhaseName.SUN_RISE, sun.getPhase().getName());
|
||||
}
|
||||
|
||||
@@ -298,7 +408,7 @@ public class SunCalcTest {
|
||||
TimeZone tZone = TimeZone.getTimeZone("Europe/London");
|
||||
Calendar tDate = SunCalcTest.newCalendar(2020, Calendar.MAY, 13, 5, 18, tZone);
|
||||
|
||||
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true);
|
||||
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true, TIME_ZONE, Locale.ROOT);
|
||||
assertEquals(SunPhaseName.DAYLIGHT, sun.getPhase().getName());
|
||||
}
|
||||
|
||||
@@ -326,25 +436,26 @@ public class SunCalcTest {
|
||||
* @return
|
||||
*/
|
||||
private static Calendar newCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, TimeZone zone) {
|
||||
Calendar result = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute);
|
||||
result.setTimeZone(zone);
|
||||
Calendar result = new GregorianCalendar(zone, Locale.ROOT);
|
||||
result.set(year, month, dayOfMonth, hourOfDay, minute);
|
||||
|
||||
return result;
|
||||
return DateTimeUtils.truncateToMinute(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAstroAndMeteoSeasons() {
|
||||
Sun meteoSun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE,
|
||||
true);
|
||||
true, TIME_ZONE, Locale.ROOT);
|
||||
Sun equiSun = sunCalc.getSunInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, AMSTERDAM_ALTITUDE,
|
||||
false);
|
||||
false, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertEquals(meteoSun.getSeason().getSpring().get(Calendar.MONTH),
|
||||
equiSun.getSeason().getSpring().get(Calendar.MONTH));
|
||||
assertEquals(meteoSun.getSeason().getSpring().get(Calendar.YEAR),
|
||||
equiSun.getSeason().getSpring().get(Calendar.YEAR));
|
||||
assertEquals(1, meteoSun.getSeason().getSpring().get(Calendar.DAY_OF_MONTH));
|
||||
assertFalse(meteoSun.getSeason().getSpring().get(Calendar.DAY_OF_MONTH) == equiSun.getSeason().getSpring()
|
||||
.get(Calendar.DAY_OF_MONTH));
|
||||
Calendar cal = meteoSun.getSeason().getSpring();
|
||||
assertNotNull(cal);
|
||||
Calendar cal2 = equiSun.getSeason().getSpring();
|
||||
assertNotNull(cal2);
|
||||
assertEquals(cal.get(Calendar.MONTH), cal2.get(Calendar.MONTH));
|
||||
assertEquals(cal.get(Calendar.YEAR), cal2.get(Calendar.YEAR));
|
||||
assertEquals(1, cal.get(Calendar.DAY_OF_MONTH));
|
||||
assertFalse(cal.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH));
|
||||
}
|
||||
}
|
||||
|
||||
+94
-23
@@ -12,9 +12,11 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.job;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -32,6 +34,8 @@ import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
@NonNullByDefault
|
||||
public class JobTest {
|
||||
|
||||
private final TimeZone TIME_ZONE = TimeZone.getTimeZone("Asia/Tbilisi");
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
}
|
||||
@@ -43,35 +47,101 @@ public class JobTest {
|
||||
config.earliest = "08:00";
|
||||
config.latest = "22:00";
|
||||
config.forceEvent = true;
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0);
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0, TIME_ZONE, Locale.ROOT);
|
||||
Range startNull = new Range(null, pointInTime);
|
||||
Range endNull = new Range(pointInTime, null);
|
||||
Range bothNull = new Range(null, null);
|
||||
Range bothNNShouldCorrect = new Range(DateTimeUtils.createCalendarForToday(6, 0),
|
||||
DateTimeUtils.createCalendarForToday(22, 0));
|
||||
Range bothNNShouldCorrect = new Range(DateTimeUtils.createCalendarForToday(6, 0, TIME_ZONE, Locale.ROOT),
|
||||
DateTimeUtils.createCalendarForToday(23, 10, TIME_ZONE, Locale.ROOT));
|
||||
Range bothNNShouldNotCorrect = new Range(pointInTime, pointInTime);
|
||||
|
||||
// act
|
||||
Range startNullResult = Job.adjustRangeToConfig(startNull, config);
|
||||
Range endNullResult = Job.adjustRangeToConfig(endNull, config);
|
||||
Range bothNullResult = Job.adjustRangeToConfig(bothNull, config);
|
||||
Range bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config);
|
||||
Range bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config);
|
||||
Range startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT);
|
||||
Range endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT);
|
||||
Range bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT);
|
||||
Range bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT);
|
||||
Range bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE,
|
||||
Locale.ROOT);
|
||||
|
||||
Calendar fixedStart = DateTimeUtils.getAdjustedEarliest(pointInTime, config);
|
||||
Calendar fixdedEnd = DateTimeUtils.getAdjustedLatest(pointInTime, config);
|
||||
Calendar fixedEnd = DateTimeUtils.getAdjustedLatest(pointInTime, config);
|
||||
|
||||
// assert
|
||||
assertEquals(fixedStart.getTime(), startNullResult.getStart().getTime());
|
||||
assertEquals(pointInTime.getTime(), startNullResult.getEnd().getTime());
|
||||
Calendar startNullResultStart = startNullResult.getStart();
|
||||
Calendar startNullResultEnd = startNullResult.getEnd();
|
||||
assertNotNull(startNullResultStart);
|
||||
assertNotNull(startNullResultEnd);
|
||||
assertEquals(fixedStart.getTime(), startNullResultStart.getTime());
|
||||
assertEquals(pointInTime.getTime(), startNullResultEnd.getTime());
|
||||
assertEquals(pointInTime, endNullResult.getStart());
|
||||
assertEquals(fixdedEnd, endNullResult.getEnd());
|
||||
assertEquals(fixedEnd, endNullResult.getEnd());
|
||||
assertEquals(fixedStart, bothNullResult.getStart());
|
||||
assertEquals(fixdedEnd, bothNullResult.getEnd());
|
||||
assertEquals(fixedEnd, bothNullResult.getEnd());
|
||||
assertEquals(fixedStart, bothNNShouldCorrectResult.getStart());
|
||||
assertEquals(fixdedEnd, bothNNShouldCorrectResult.getEnd());
|
||||
assertEquals(fixedEnd, bothNNShouldCorrectResult.getEnd());
|
||||
assertEquals(pointInTime, bothNNSouldNotCorrectResult.getStart());
|
||||
assertEquals(pointInTime, bothNNSouldNotCorrectResult.getEnd());
|
||||
|
||||
// arrange more (add negative offset)
|
||||
config.offset = -49;
|
||||
Calendar newPointInTime = (Calendar) pointInTime.clone();
|
||||
newPointInTime.add(Calendar.MINUTE, -49);
|
||||
Calendar outerFixedPoint = (Calendar) fixedEnd.clone();
|
||||
fixedEnd.add(Calendar.MINUTE, -49);
|
||||
|
||||
// act again
|
||||
startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT);
|
||||
endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT);
|
||||
bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT);
|
||||
bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT);
|
||||
bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// assert again
|
||||
startNullResultStart = startNullResult.getStart();
|
||||
startNullResultEnd = startNullResult.getEnd();
|
||||
assertNotNull(startNullResultStart);
|
||||
assertNotNull(startNullResultEnd);
|
||||
assertEquals(fixedStart.getTime(), startNullResultStart.getTime());
|
||||
assertEquals(newPointInTime.getTime(), startNullResultEnd.getTime());
|
||||
assertEquals(newPointInTime, endNullResult.getStart());
|
||||
assertEquals(fixedEnd, endNullResult.getEnd());
|
||||
assertEquals(fixedStart, bothNullResult.getStart());
|
||||
assertEquals(fixedEnd, bothNullResult.getEnd());
|
||||
assertEquals(fixedStart, bothNNShouldCorrectResult.getStart());
|
||||
assertEquals(outerFixedPoint, bothNNShouldCorrectResult.getEnd());
|
||||
assertEquals(newPointInTime, bothNNSouldNotCorrectResult.getStart());
|
||||
assertEquals(newPointInTime, bothNNSouldNotCorrectResult.getEnd());
|
||||
|
||||
// arrange even more (add negative offset)
|
||||
config.offset = 93;
|
||||
newPointInTime = (Calendar) pointInTime.clone();
|
||||
newPointInTime.add(Calendar.MINUTE, 93);
|
||||
fixedEnd.add(Calendar.MINUTE, 49);
|
||||
outerFixedPoint = (Calendar) fixedStart.clone();
|
||||
fixedStart.add(Calendar.MINUTE, 93);
|
||||
|
||||
// act yet again
|
||||
startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT);
|
||||
endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT);
|
||||
bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT);
|
||||
bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT);
|
||||
bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// assert yet again
|
||||
startNullResultStart = startNullResult.getStart();
|
||||
startNullResultEnd = startNullResult.getEnd();
|
||||
assertNotNull(startNullResultStart);
|
||||
assertNotNull(startNullResultEnd);
|
||||
assertEquals(fixedStart.getTime(), startNullResultStart.getTime());
|
||||
assertEquals(newPointInTime.getTime(), startNullResultEnd.getTime());
|
||||
assertEquals(newPointInTime, endNullResult.getStart());
|
||||
assertEquals(fixedEnd, endNullResult.getEnd());
|
||||
assertEquals(fixedStart, bothNullResult.getStart());
|
||||
assertEquals(fixedEnd, bothNullResult.getEnd());
|
||||
assertEquals(outerFixedPoint, bothNNShouldCorrectResult.getStart());
|
||||
assertEquals(fixedEnd, bothNNShouldCorrectResult.getEnd());
|
||||
assertEquals(newPointInTime, bothNNSouldNotCorrectResult.getStart());
|
||||
assertEquals(newPointInTime, bothNNSouldNotCorrectResult.getEnd());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -81,20 +151,21 @@ public class JobTest {
|
||||
config.earliest = "08:00";
|
||||
config.latest = "22:00";
|
||||
config.forceEvent = false;
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0);
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0, TIME_ZONE, Locale.ROOT);
|
||||
Range startNull = new Range(null, pointInTime);
|
||||
Range endNull = new Range(pointInTime, null);
|
||||
Range bothNull = new Range(null, null);
|
||||
Range bothNNShouldCorrect = new Range(DateTimeUtils.createCalendarForToday(6, 0),
|
||||
DateTimeUtils.createCalendarForToday(22, 0));
|
||||
Range bothNNShouldCorrect = new Range(DateTimeUtils.createCalendarForToday(6, 0, TIME_ZONE, Locale.ROOT),
|
||||
DateTimeUtils.createCalendarForToday(23, 10, TIME_ZONE, Locale.ROOT));
|
||||
Range bothNNShouldNotCorrect = new Range(pointInTime, pointInTime);
|
||||
|
||||
// act
|
||||
Range startNullResult = Job.adjustRangeToConfig(startNull, config);
|
||||
Range endNullResult = Job.adjustRangeToConfig(endNull, config);
|
||||
Range bothNullResult = Job.adjustRangeToConfig(bothNull, config);
|
||||
Range bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config);
|
||||
Range bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config);
|
||||
Range startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT);
|
||||
Range endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT);
|
||||
Range bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT);
|
||||
Range bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT);
|
||||
Range bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE,
|
||||
Locale.ROOT);
|
||||
|
||||
Calendar fixedStart = DateTimeUtils.getAdjustedEarliest(pointInTime, config);
|
||||
Calendar fixdedEnd = DateTimeUtils.getAdjustedLatest(pointInTime, config);
|
||||
|
||||
+5
-15
@@ -14,7 +14,7 @@ package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -37,7 +37,7 @@ public class SunTest {
|
||||
private Sun sun;
|
||||
private AstroChannelConfig config;
|
||||
|
||||
private static final ZoneId ZONE = ZoneId.systemDefault();
|
||||
private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Asia/Gaza");
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
@@ -49,7 +49,7 @@ public class SunTest {
|
||||
public void testConstructor() throws Exception {
|
||||
assertNotNull(sun.getPhase());
|
||||
assertEquals(UnDefType.UNDEF,
|
||||
PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"), config, sun, ZONE));
|
||||
PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"), config, sun, TIME_ZONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -57,7 +57,7 @@ public class SunTest {
|
||||
sun.getPhase().setName(null);
|
||||
|
||||
assertEquals(UnDefType.UNDEF,
|
||||
PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"), config, sun, ZONE));
|
||||
PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"), config, sun, TIME_ZONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -65,17 +65,7 @@ public class SunTest {
|
||||
sun.getPhase().setName(SunPhaseName.DAYLIGHT);
|
||||
|
||||
assertEquals(new StringType("DAYLIGHT"),
|
||||
PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"), config, sun, ZONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateWhenNullPhase() throws Exception {
|
||||
sun.setPhase(null);
|
||||
|
||||
assertNull(sun.getPhase());
|
||||
|
||||
assertThrows(NullPointerException.class, () -> assertEquals(UnDefType.UNDEF,
|
||||
PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"), config, sun, ZONE)));
|
||||
PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"), config, sun, TIME_ZONE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+15
-11
@@ -12,10 +12,11 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.util;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -48,24 +49,25 @@ public class DateTimeUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGetSeasonAmsterdam() {
|
||||
final Season season = seasonCalc.getSeason(DEC_10_2020, AMSTERDAM_LATITUDE, true);
|
||||
final Season season = seasonCalc.getSeason(DEC_10_2020, AMSTERDAM_LATITUDE, true, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertNextSeason(season.getSpring(), 2020, JAN_20_2020, season);
|
||||
assertNextSeason(season.getSummer(), 2020, MAY_20_2020, season);
|
||||
assertNextSeason(season.getWinter(), 2020, SEPT_20_2020, season);
|
||||
assertNextSeason(seasonCalc.getSeason(DEC_10_2021, AMSTERDAM_LATITUDE, true).getSpring(), 2021, DEC_10_2020,
|
||||
season);
|
||||
assertNextSeason(
|
||||
seasonCalc.getSeason(DEC_10_2021, AMSTERDAM_LATITUDE, true, TIME_ZONE, Locale.ROOT).getSpring(), 2021,
|
||||
DEC_10_2020, season);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSeasonSydney() {
|
||||
final Season season = seasonCalc.getSeason(DEC_10_2020, SYDNEY_LATITUDE, true);
|
||||
final Season season = seasonCalc.getSeason(DEC_10_2020, SYDNEY_LATITUDE, true, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
assertNextSeason(season.getAutumn(), 2020, JAN_20_2020, season);
|
||||
assertNextSeason(season.getWinter(), 2020, MAY_20_2020, season);
|
||||
assertNextSeason(season.getSummer(), 2020, SEPT_20_2020, season);
|
||||
assertNextSeason(seasonCalc.getSeason(DEC_10_2021, SYDNEY_LATITUDE, true).getAutumn(), 2021, DEC_10_2020,
|
||||
season);
|
||||
assertNextSeason(seasonCalc.getSeason(DEC_10_2021, SYDNEY_LATITUDE, true, TIME_ZONE, Locale.ROOT).getAutumn(),
|
||||
2021, DEC_10_2020, season);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -75,8 +77,8 @@ public class DateTimeUtilsTest {
|
||||
Calendar truncated = DateTimeUtils.truncateToMidnight(cal);
|
||||
assertEquals(truncated, target);
|
||||
Calendar endOfDay = DateTimeUtils.endOfDayDate(cal);
|
||||
Calendar target2 = new GregorianCalendar(2021, 9, 30, 23, 59, 59);
|
||||
target2.setTimeZone(TIME_ZONE);
|
||||
Calendar target2 = newCalendar(2021, 9, 30, 23, 59, TIME_ZONE);
|
||||
target2.set(Calendar.SECOND, 59);
|
||||
target2.set(Calendar.MILLISECOND, 999);
|
||||
assertEquals(endOfDay, target2);
|
||||
}
|
||||
@@ -85,12 +87,14 @@ public class DateTimeUtilsTest {
|
||||
final Calendar nextSeason = DateTimeUtils.getNext(date, season.getSpring(), season.getSummer(),
|
||||
season.getAutumn(), season.getWinter());
|
||||
assertEquals(expectedSeason, nextSeason, "Should return the expected season name.");
|
||||
assertNotNull(nextSeason);
|
||||
assertEquals(expectedYear, nextSeason.get(Calendar.YEAR), "Should return the year matching the next season.");
|
||||
}
|
||||
|
||||
private static Calendar newCalendar(int year, int month, int dayOfMonth, int hourOfDay, int minute, TimeZone zone) {
|
||||
Calendar result = new GregorianCalendar(year, month, dayOfMonth, hourOfDay, minute);
|
||||
result.setTimeZone(zone);
|
||||
Calendar result = new GregorianCalendar(zone, Locale.ROOT);
|
||||
result.set(Calendar.MILLISECOND, 0);
|
||||
result.set(year, month, dayOfMonth, hourOfDay, minute, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+3
-1
@@ -24,6 +24,7 @@ import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
import org.openhab.binding.astro.internal.handler.SunHandler;
|
||||
import org.openhab.binding.astro.internal.model.Sun;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Channel;
|
||||
@@ -64,8 +65,9 @@ public class AstroCommandTest {
|
||||
ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
|
||||
CronScheduler cronScheduler = mock(CronScheduler.class);
|
||||
TimeZoneProvider timeZoneProvider = mock(TimeZoneProvider.class);
|
||||
LocaleProvider localeProvider = mock(LocaleProvider.class);
|
||||
when(timeZoneProvider.getTimeZone()).thenReturn(ZoneId.systemDefault());
|
||||
AstroThingHandler sunHandler = spy(new SunHandler(thing, cronScheduler, timeZoneProvider));
|
||||
AstroThingHandler sunHandler = spy(new SunHandler(thing, cronScheduler, timeZoneProvider, localeProvider));
|
||||
|
||||
// Required from the AstroThingHandler to send the status update
|
||||
doReturn(true).when(callback).isChannelLinked(eq(channelUID));
|
||||
|
||||
+3
-1
@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
import org.openhab.binding.astro.internal.handler.SunHandler;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Thing;
|
||||
@@ -147,8 +148,9 @@ public class AstroValidConfigurationTest {
|
||||
ThingHandlerCallback callback = mock(ThingHandlerCallback.class);
|
||||
CronScheduler cronScheduler = mock(CronScheduler.class);
|
||||
TimeZoneProvider timeZoneProvider = mock(TimeZoneProvider.class);
|
||||
LocaleProvider localeProvider = mock(LocaleProvider.class);
|
||||
when(timeZoneProvider.getTimeZone()).thenReturn(ZoneId.systemDefault());
|
||||
ThingHandler sunHandler = new SunHandler(thing, cronScheduler, timeZoneProvider);
|
||||
ThingHandler sunHandler = new SunHandler(thing, cronScheduler, timeZoneProvider, localeProvider);
|
||||
sunHandler.setCallback(callback);
|
||||
|
||||
sunHandler.initialize();
|
||||
|
||||
+8
-3
@@ -23,6 +23,8 @@ import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
@@ -67,7 +69,8 @@ public class AstroStateTest {
|
||||
|
||||
private void assertStateUpdate(String thingID, String channelId, State expectedState) throws Exception {
|
||||
ChannelUID testItemChannelUID = new ChannelUID(getThingUID(thingID), channelId);
|
||||
State state = PropertyUtils.getState(testItemChannelUID, new AstroChannelConfig(), getPlanet(thingID), ZONE_ID);
|
||||
State state = PropertyUtils.getState(testItemChannelUID, new AstroChannelConfig(), getPlanet(thingID),
|
||||
TimeZone.getTimeZone(ZONE_ID));
|
||||
assertEquals(expectedState, state);
|
||||
}
|
||||
|
||||
@@ -89,10 +92,12 @@ public class AstroStateTest {
|
||||
switch (thingID) {
|
||||
case (TEST_SUN_THING_ID):
|
||||
SunCalc sunCalc = new SunCalc();
|
||||
return sunCalc.getSunInfo(calendar, TEST_LATITUDE, TEST_LONGITUDE, null, false);
|
||||
return sunCalc.getSunInfo(calendar, TEST_LATITUDE, TEST_LONGITUDE, null, false,
|
||||
TimeZone.getTimeZone(ZONE_ID), Locale.getDefault());
|
||||
case (TEST_MOON_THING_ID):
|
||||
MoonCalc moonCalc = new MoonCalc();
|
||||
return moonCalc.getMoonInfo(calendar, TEST_LATITUDE, TEST_LONGITUDE);
|
||||
return moonCalc.getMoonInfo(calendar, TEST_LATITUDE, TEST_LONGITUDE, TimeZone.getTimeZone(ZONE_ID),
|
||||
Locale.getDefault());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user