mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[astro] Remove use of reflection (#20000)
* Remove the use of reflection Signed-off-by: Ravi Nadahar <nadahar@rediffmail.com>
This commit is contained in:
+97
-2
@@ -49,6 +49,103 @@ public final class AstroBindingConstants {
|
||||
public static final String EVENT_PHASE_FULL = "FULL";
|
||||
public static final String EVENT_PHASE_NEW = "NEW";
|
||||
|
||||
// regular channelIds
|
||||
|
||||
public static final String CHANNEL_ID_MOON_RISE_START = "rise#start";
|
||||
public static final String CHANNEL_ID_MOON_RISE_END = "rise#end";
|
||||
public static final String CHANNEL_ID_MOON_RISE_DURATION = "rise#duration";
|
||||
public static final String CHANNEL_ID_MOON_SET_START = "set#start";
|
||||
public static final String CHANNEL_ID_MOON_SET_END = "set#end";
|
||||
public static final String CHANNEL_ID_MOON_SET_DURATION = "set#duration";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_FIRST_QUARTER = "phase#firstQuarter";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_THIRD_QUARTER = "phase#thirdQuarter";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_FULL = "phase#full";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_NEW = "phase#new";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_AGE = "phase#age";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_AGE_DEGREE = "phase#ageDegree";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_AGE_PERCENT = "phase#agePercent";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_ILLUMINATION = "phase#illumination";
|
||||
public static final String CHANNEL_ID_MOON_PHASE_NAME = "phase#name";
|
||||
public static final String CHANNEL_ID_MOON_ECLIPSE_TOTAL = "eclipse#total";
|
||||
public static final String CHANNEL_ID_MOON_ECLIPSE_TOTAL_ELEVATION = "eclipse#totalElevation";
|
||||
public static final String CHANNEL_ID_MOON_ECLIPSE_PARTIAL = "eclipse#partial";
|
||||
public static final String CHANNEL_ID_MOON_ECLIPSE_PARTIAL_ELEVATION = "eclipse#partialElevation";
|
||||
public static final String CHANNEL_ID_MOON_DISTANCE_DATE = "distance#date";
|
||||
public static final String CHANNEL_ID_MOON_DISTANCE_DISTANCE = "distance#distance";
|
||||
public static final String CHANNEL_ID_MOON_PERIGEE_DATE = "perigee#date";
|
||||
public static final String CHANNEL_ID_MOON_PERIGEE_DISTANCE = "perigee#distance";
|
||||
public static final String CHANNEL_ID_MOON_APOGEE_DATE = "apogee#date";
|
||||
public static final String CHANNEL_ID_MOON_APOGEE_DISTANCE = "apogee#distance";
|
||||
public static final String CHANNEL_ID_MOON_POSITION_AZIMUTH = "position#azimuth";
|
||||
public static final String CHANNEL_ID_MOON_POSITION_ELEVATION = "position#elevation";
|
||||
public static final String CHANNEL_ID_MOON_POSITION_SHADE_LENGTH = "position#shadeLength";
|
||||
public static final String CHANNEL_ID_MOON_ZODIAC_SIGN = "zodiac#sign";
|
||||
|
||||
public static final String CHANNEL_ID_SUN_RISE_START = "rise#start";
|
||||
public static final String CHANNEL_ID_SUN_RISE_END = "rise#end";
|
||||
public static final String CHANNEL_ID_SUN_RISE_DURATION = "rise#duration";
|
||||
public static final String CHANNEL_ID_SUN_SET_START = "set#start";
|
||||
public static final String CHANNEL_ID_SUN_SET_END = "set#end";
|
||||
public static final String CHANNEL_ID_SUN_SET_DURATION = "set#duration";
|
||||
public static final String CHANNEL_ID_SUN_NOON_START = "noon#start";
|
||||
public static final String CHANNEL_ID_SUN_NOON_END = "noon#end";
|
||||
public static final String CHANNEL_ID_SUN_NOON_DURATION = "noon#duration";
|
||||
public static final String CHANNEL_ID_SUN_NIGHT_START = "night#start";
|
||||
public static final String CHANNEL_ID_SUN_NIGHT_END = "night#end";
|
||||
public static final String CHANNEL_ID_SUN_NIGHT_DURATION = "night#duration";
|
||||
public static final String CHANNEL_ID_SUN_MORNING_NIGHT_START = "morningNight#start";
|
||||
public static final String CHANNEL_ID_SUN_MORNING_NIGHT_END = "morningNight#end";
|
||||
public static final String CHANNEL_ID_SUN_MORNING_NIGHT_DURATION = "morningNight#duration";
|
||||
public static final String CHANNEL_ID_SUN_ASTRO_DAWN_START = "astroDawn#start";
|
||||
public static final String CHANNEL_ID_SUN_ASTRO_DAWN_END = "astroDawn#end";
|
||||
public static final String CHANNEL_ID_SUN_ASTRO_DAWN_DURATION = "astroDawn#duration";
|
||||
public static final String CHANNEL_ID_SUN_NAUTIC_DAWN_START = "nauticDawn#start";
|
||||
public static final String CHANNEL_ID_SUN_NAUTIC_DAWN_END = "nauticDawn#end";
|
||||
public static final String CHANNEL_ID_SUN_NAUTIC_DAWN_DURATION = "nauticDawn#duration";
|
||||
public static final String CHANNEL_ID_SUN_CIVIL_DAWN_START = "civilDawn#start";
|
||||
public static final String CHANNEL_ID_SUN_CIVIL_DAWN_END = "civilDawn#end";
|
||||
public static final String CHANNEL_ID_SUN_CIVIL_DAWN_DURATION = "civilDawn#duration";
|
||||
public static final String CHANNEL_ID_SUN_ASTRO_DUSK_START = "astroDusk#start";
|
||||
public static final String CHANNEL_ID_SUN_ASTRO_DUSK_END = "astroDusk#end";
|
||||
public static final String CHANNEL_ID_SUN_ASTRO_DUSK_DURATION = "astroDusk#duration";
|
||||
public static final String CHANNEL_ID_SUN_NAUTIC_DUSK_START = "nauticDusk#start";
|
||||
public static final String CHANNEL_ID_SUN_NAUTIC_DUSK_END = "nauticDusk#end";
|
||||
public static final String CHANNEL_ID_SUN_NAUTIC_DUSK_DURATION = "nauticDusk#duration";
|
||||
public static final String CHANNEL_ID_SUN_CIVIL_DUSK_START = "civilDusk#start";
|
||||
public static final String CHANNEL_ID_SUN_CIVIL_DUSK_END = "civilDusk#end";
|
||||
public static final String CHANNEL_ID_SUN_CIVIL_DUSK_DURATION = "civilDusk#duration";
|
||||
public static final String CHANNEL_ID_SUN_EVENING_NIGHT_START = "eveningNight#start";
|
||||
public static final String CHANNEL_ID_SUN_EVENING_NIGHT_END = "eveningNight#end";
|
||||
public static final String CHANNEL_ID_SUN_EVENING_NIGHT_DURATION = "eveningNight#duration";
|
||||
public static final String CHANNEL_ID_SUN_DAYLIGHT_START = "daylight#start";
|
||||
public static final String CHANNEL_ID_SUN_DAYLIGHT_END = "daylight#end";
|
||||
public static final String CHANNEL_ID_SUN_DAYLIGHT_DURATION = "daylight#duration";
|
||||
public static final String CHANNEL_ID_SUN_POSITION_AZIMUTH = "position#azimuth";
|
||||
public static final String CHANNEL_ID_SUN_POSITION_ELEVATION = "position#elevation";
|
||||
public static final String CHANNEL_ID_SUN_POSITION_SHADE_LENGTH = "position#shadeLength";
|
||||
public static final String CHANNEL_ID_SUN_RADIATION_DIRECT = "radiation#direct";
|
||||
public static final String CHANNEL_ID_SUN_RADIATION_DIFFUSE = "radiation#diffuse";
|
||||
public static final String CHANNEL_ID_SUN_RADIATION_TOTAL = "radiation#total";
|
||||
public static final String CHANNEL_ID_SUN_ZODIAC_START = "zodiac#start";
|
||||
public static final String CHANNEL_ID_SUN_ZODIAC_END = "zodiac#end";
|
||||
public static final String CHANNEL_ID_SUN_ZODIAC_SIGN = "zodiac#sign";
|
||||
public static final String CHANNEL_ID_SUN_SEASON_NAME = "season#name";
|
||||
public static final String CHANNEL_ID_SUN_SEASON_SPRING = "season#spring";
|
||||
public static final String CHANNEL_ID_SUN_SEASON_SUMMER = "season#summer";
|
||||
public static final String CHANNEL_ID_SUN_SEASON_AUTUMN = "season#autumn";
|
||||
public static final String CHANNEL_ID_SUN_SEASON_WINTER = "season#winter";
|
||||
public static final String CHANNEL_ID_SUN_SEASON_NEXT_NAME = "season#nextName";
|
||||
public static final String CHANNEL_ID_SUN_SEASON_TIME_LEFT = "season#timeLeft";
|
||||
public static final String CHANNEL_ID_SUN_ECLIPSE_TOTAL = "eclipse#total";
|
||||
public static final String CHANNEL_ID_SUN_ECLIPSE_TOTAL_ELEVATION = "eclipse#totalElevation";
|
||||
public static final String CHANNEL_ID_SUN_ECLIPSE_PARTIAL = "eclipse#partial";
|
||||
public static final String CHANNEL_ID_SUN_ECLIPSE_PARTIAL_ELEVATION = "eclipse#partialElevation";
|
||||
public static final String CHANNEL_ID_SUN_ECLIPSE_RING = "eclipse#ring";
|
||||
public static final String CHANNEL_ID_SUN_ECLIPSE_RING_ELEVATION = "eclipse#ringElevation";
|
||||
public static final String CHANNEL_ID_SUN_PHASE_NAME = "phase#name";
|
||||
public static final String CHANNEL_ID_SUN_CIRCADIAN_BRIGHTNESS = "circadian#brightness";
|
||||
public static final String CHANNEL_ID_SUN_CIRCADIAN_TEMPERATURE = "circadian#temperature";
|
||||
|
||||
// event channelIds
|
||||
public static final String EVENT_CHANNEL_ID_MOON_PHASE = "phase#event";
|
||||
public static final String EVENT_CHANNEL_ID_ECLIPSE = "eclipse#event";
|
||||
@@ -66,6 +163,4 @@ public final class AstroBindingConstants {
|
||||
public static final String EVENT_CHANNEL_ID_CIVIL_DUSK = "civilDusk#event";
|
||||
public static final String EVENT_CHANNEL_ID_EVENING_NIGHT = "eveningNight#event";
|
||||
public static final String EVENT_CHANNEL_ID_DAYLIGHT = "daylight#event";
|
||||
|
||||
public static final String CHANNEL_ID_SUN_PHASE_NAME = "phase#name";
|
||||
}
|
||||
|
||||
+3
-2
@@ -14,6 +14,7 @@ package org.openhab.binding.astro.internal;
|
||||
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
|
||||
|
||||
import java.time.InstantSource;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@@ -65,9 +66,9 @@ public class AstroHandlerFactory extends BaseThingHandlerFactory {
|
||||
ThingTypeUID thingTypeUID = thing.getThingTypeUID();
|
||||
AstroThingHandler thingHandler = null;
|
||||
if (thingTypeUID.equals(THING_TYPE_SUN)) {
|
||||
thingHandler = new SunHandler(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
thingHandler = new SunHandler(thing, scheduler, timeZoneProvider, localeProvider, InstantSource.system());
|
||||
} else if (thingTypeUID.equals(THING_TYPE_MOON)) {
|
||||
thingHandler = new MoonHandler(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
thingHandler = new MoonHandler(thing, scheduler, timeZoneProvider, localeProvider, InstantSource.system());
|
||||
}
|
||||
return thingHandler;
|
||||
}
|
||||
|
||||
+13
-1
@@ -16,6 +16,7 @@ import static org.openhab.binding.astro.internal.util.MathUtils.*;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@@ -51,6 +52,17 @@ public class MoonCalc {
|
||||
private static final double FIRST_QUARTER = 0.25;
|
||||
private static final double LAST_QUARTER = 0.75;
|
||||
|
||||
private final InstantSource instantSource;
|
||||
|
||||
/**
|
||||
* Creates a new instance using the specified {@link InstantSource}.
|
||||
*
|
||||
* @param instantSource the source of the current time.
|
||||
*/
|
||||
public MoonCalc(InstantSource instantSource) {
|
||||
this.instantSource = instantSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates all moon data at the specified coordinates
|
||||
*/
|
||||
@@ -135,7 +147,7 @@ public class MoonCalc {
|
||||
return;
|
||||
}
|
||||
long ageRangeTimeMillis = cal.getTimeInMillis() - parentNewMoonMillis;
|
||||
long ageCurrentMillis = System.currentTimeMillis() - parentNewMoonMillis;
|
||||
long ageCurrentMillis = instantSource.millis() - parentNewMoonMillis;
|
||||
double agePercent = ageRangeTimeMillis != 0 ? ageCurrentMillis * 100.0 / ageRangeTimeMillis : 0;
|
||||
phase.setAgePercent(agePercent);
|
||||
phase.setAgeDegree(3.6 * agePercent);
|
||||
|
||||
+6
-3
@@ -13,6 +13,7 @@
|
||||
package org.openhab.binding.astro.internal.calc;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
@@ -40,9 +41,11 @@ public class SeasonCalc {
|
||||
/**
|
||||
* Returns the seasons of the year of the specified calendar.
|
||||
*/
|
||||
public static Season calculate(int year, double latitude, boolean useMeteorologicalSeason, TimeZone zone) {
|
||||
return new Season(latitude, useMeteorologicalSeason, zone, calcEquiSol(3, year - 1), calcEquiSol(0, year),
|
||||
calcEquiSol(1, year), calcEquiSol(2, year), calcEquiSol(3, year), calcEquiSol(0, year + 1));
|
||||
public static Season calculate(int year, double latitude, boolean useMeteorologicalSeason, TimeZone zone,
|
||||
InstantSource instantSource) {
|
||||
return new Season(latitude, useMeteorologicalSeason, zone, instantSource, calcEquiSol(3, year - 1),
|
||||
calcEquiSol(0, year), calcEquiSol(1, year), calcEquiSol(2, year), calcEquiSol(3, year),
|
||||
calcEquiSol(0, year + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-2
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.calc;
|
||||
|
||||
import java.time.InstantSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
@@ -65,6 +66,17 @@ public class SunCalc {
|
||||
private static final int CURVE_TIME_INTERVAL = 20; // 20 minutes
|
||||
private static final double JD_ONE_MINUTE_FRACTION = 1.0 / 60 / 24;
|
||||
|
||||
private final InstantSource instantSource;
|
||||
|
||||
/**
|
||||
* Creates a new instance using the specified {@link InstantSource}.
|
||||
*
|
||||
* @param instantSource the source of the current time.
|
||||
*/
|
||||
public SunCalc(InstantSource instantSource) {
|
||||
this.instantSource = instantSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the sun position (azimuth and elevation).
|
||||
*/
|
||||
@@ -222,7 +234,7 @@ public class SunCalc {
|
||||
|
||||
// eclipse
|
||||
Eclipse eclipse = sun.getEclipse();
|
||||
MoonCalc mc = new MoonCalc();
|
||||
MoonCalc mc = new MoonCalc(instantSource);
|
||||
|
||||
eclipse.getKinds().forEach(eclipseKind -> {
|
||||
double jdate = mc.getEclipse(calendar, EclipseType.SUN, j, eclipseKind);
|
||||
@@ -237,7 +249,7 @@ public class SunCalc {
|
||||
Season season = sun.getSeason();
|
||||
var year = calendar.get(Calendar.YEAR);
|
||||
if (season == null || season.getYear() != year) {
|
||||
sun.setSeason(SeasonCalc.calculate(year, latitude, useMeteorologicalSeason, zone));
|
||||
sun.setSeason(SeasonCalc.calculate(year, latitude, useMeteorologicalSeason, zone, instantSource));
|
||||
}
|
||||
|
||||
// phase
|
||||
|
||||
+59
-7
@@ -17,13 +17,17 @@ import static org.openhab.core.thing.type.ChannelKind.TRIGGER;
|
||||
import static org.openhab.core.types.RefreshType.REFRESH;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collection;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -44,9 +48,12 @@ import org.openhab.binding.astro.internal.job.Job;
|
||||
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.binding.astro.internal.util.DateTimeUtils;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.scheduler.ScheduledCompletableFuture;
|
||||
import org.openhab.core.thing.Channel;
|
||||
@@ -95,12 +102,16 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
// All access must be guarded by "monitor"
|
||||
private @Nullable ScheduledCompletableFuture<?> dailyJob;
|
||||
|
||||
/** The source of the current time */
|
||||
protected final InstantSource instantSource;
|
||||
|
||||
public AstroThingHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider,
|
||||
LocaleProvider localeProvider) {
|
||||
LocaleProvider localeProvider, InstantSource instantSource) {
|
||||
super(thing);
|
||||
this.cronScheduler = scheduler;
|
||||
this.timeZoneProvider = timeZoneProvider;
|
||||
this.localeProvider = localeProvider;
|
||||
this.instantSource = instantSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -188,15 +199,23 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
AstroChannelConfig config = channel.getConfiguration().as(AstroChannelConfig.class);
|
||||
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);
|
||||
updateState(channelUID, getState(channel));
|
||||
} catch (IllegalArgumentException e) {
|
||||
logger.warn("Can't retrieve the state for channel '{}': {}", channelUID, e.getMessage());
|
||||
logger.trace("", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the channel state and convert it to an appropriate {@link State} instance.
|
||||
*
|
||||
* @param channel the {@link Channel} whose {@link State} to get.
|
||||
* @return The resulting channel {@link State}.
|
||||
* @throws IllegalArgumentException If the channel has a state of an unsupported type.
|
||||
*/
|
||||
protected abstract State getState(Channel channel);
|
||||
|
||||
/**
|
||||
* Schedules a positional and a daily job at midnight for Astro calculation and starts it immediately too. Removes
|
||||
* already scheduled jobs first.
|
||||
@@ -331,6 +350,7 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
* Adds the provided {@link Job} to the queue (cannot be {@code null})
|
||||
*/
|
||||
public void schedule(Job job, Calendar eventAt) {
|
||||
// We don't use instantSource here, because we always want to schedule relative to the system clock
|
||||
long sleepTime = eventAt.getTimeInMillis() - System.currentTimeMillis();
|
||||
if (sleepTime >= 0L) {
|
||||
schedule(job, sleepTime);
|
||||
@@ -345,6 +365,7 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
public void schedule(Job job, Instant eventAt) {
|
||||
// We don't use instantSource here, because we always want to schedule relative to the system clock
|
||||
long sleepTime = eventAt.toEpochMilli() + 1L - System.currentTimeMillis();
|
||||
if (sleepTime >= 0L) {
|
||||
schedule(job, sleepTime);
|
||||
@@ -415,4 +436,35 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
public Collection<Class<? extends ThingHandlerService>> getServices() {
|
||||
return List.of(AstroActions.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an untyped value into the appropriate {@link State} type for the specified {@link Channel}.
|
||||
*
|
||||
* @param value the {@link Object} to convert.
|
||||
* @param channel the {@link Channel} whose type to convert to.
|
||||
* @return The appropriate {@link State} instance.
|
||||
* @throws IllegalArgumentException If {@code value} is of an unsupported type.
|
||||
*/
|
||||
protected State toState(@Nullable Object value, Channel channel) {
|
||||
if (value == null) {
|
||||
return UnDefType.UNDEF;
|
||||
} else if (value instanceof State state) {
|
||||
return state;
|
||||
} else if (value instanceof Calendar cal) {
|
||||
cal.setTimeZone(TimeZone.getTimeZone(timeZoneProvider.getTimeZone()));
|
||||
GregorianCalendar gregorianCal = (GregorianCalendar) DateTimeUtils.applyConfig(cal,
|
||||
channel.getConfiguration().as(AstroChannelConfig.class));
|
||||
return new DateTimeType(gregorianCal.toInstant());
|
||||
} else if (value instanceof Instant instant) {
|
||||
return new DateTimeType(
|
||||
DateTimeUtils.applyConfig(instant, channel.getConfiguration().as(AstroChannelConfig.class)));
|
||||
} else if (value instanceof Number) {
|
||||
BigDecimal decimalValue = new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP);
|
||||
return new DecimalType(decimalValue);
|
||||
} else if (value instanceof String || value instanceof Enum) {
|
||||
return new StringType(value.toString());
|
||||
} else {
|
||||
throw new IllegalArgumentException("Unsupported value type " + value.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+90
-7
@@ -12,9 +12,11 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
|
||||
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
@@ -27,10 +29,16 @@ 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.binding.astro.internal.util.DateTimeUtils;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The MoonHandler is responsible for updating calculated moon data.
|
||||
@@ -43,15 +51,17 @@ 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 final MoonCalc moonCalc;
|
||||
private final Logger logger = LoggerFactory.getLogger(MoonHandler.class);
|
||||
private volatile @Nullable Moon moon;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public MoonHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider,
|
||||
LocaleProvider localeProvider) {
|
||||
super(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
LocaleProvider localeProvider, InstantSource instantSource) {
|
||||
super(thing, scheduler, timeZoneProvider, localeProvider, instantSource);
|
||||
moonCalc = new MoonCalc(instantSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -59,11 +69,12 @@ public class MoonHandler extends AstroThingHandler {
|
||||
ZoneId zoneId = timeZoneProvider.getTimeZone();
|
||||
TimeZone zone = TimeZone.getTimeZone(zoneId);
|
||||
Locale locale = localeProvider.getLocale();
|
||||
Moon moon = getMoonAt(ZonedDateTime.now(zoneId), locale);
|
||||
ZonedDateTime now = instantSource.instant().atZone(zone.toZoneId());
|
||||
Moon moon = getMoonAt(now, locale);
|
||||
Double latitude = thingConfig.latitude;
|
||||
Double longitude = thingConfig.longitude;
|
||||
moonCalc.setPositionalInfo(Calendar.getInstance(zone, locale), latitude != null ? latitude : 0,
|
||||
longitude != null ? longitude : 0, moon, zone, locale);
|
||||
moonCalc.setPositionalInfo(DateTimeUtils.calFromInstantSource(instantSource, zone, locale),
|
||||
latitude != null ? latitude : 0, longitude != null ? longitude : 0, moon, zone, locale);
|
||||
|
||||
moon.getEclipse().setElevations(this, timeZoneProvider);
|
||||
this.moon = moon;
|
||||
@@ -82,6 +93,78 @@ public class MoonHandler extends AstroThingHandler {
|
||||
moon = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected State getState(Channel channel) {
|
||||
Moon moon = this.moon;
|
||||
if (moon == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
switch (channel.getUID().getId()) {
|
||||
case CHANNEL_ID_MOON_RISE_START:
|
||||
return toState(moon.getRise().getStart(), channel);
|
||||
case CHANNEL_ID_MOON_RISE_END:
|
||||
return toState(moon.getRise().getEnd(), channel);
|
||||
case CHANNEL_ID_MOON_RISE_DURATION:
|
||||
return toState(moon.getRise().getDuration(), channel);
|
||||
case CHANNEL_ID_MOON_SET_START:
|
||||
return toState(moon.getSet().getStart(), channel);
|
||||
case CHANNEL_ID_MOON_SET_END:
|
||||
return toState(moon.getSet().getEnd(), channel);
|
||||
case CHANNEL_ID_MOON_SET_DURATION:
|
||||
return toState(moon.getSet().getDuration(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_FIRST_QUARTER:
|
||||
return toState(moon.getPhase().getFirstQuarter(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_THIRD_QUARTER:
|
||||
return toState(moon.getPhase().getThirdQuarter(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_FULL:
|
||||
return toState(moon.getPhase().getFull(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_NEW:
|
||||
return toState(moon.getPhase().getNew(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_AGE:
|
||||
return toState(moon.getPhase().getAge(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_AGE_DEGREE:
|
||||
return toState(moon.getPhase().getAgeDegree(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_AGE_PERCENT:
|
||||
return toState(moon.getPhase().getAgePercent(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_ILLUMINATION:
|
||||
return toState(moon.getPhase().getIllumination(), channel);
|
||||
case CHANNEL_ID_MOON_PHASE_NAME:
|
||||
return toState(moon.getPhase().getName(), channel);
|
||||
case CHANNEL_ID_MOON_ECLIPSE_TOTAL:
|
||||
return toState(moon.getEclipse().getTotal(), channel);
|
||||
case CHANNEL_ID_MOON_ECLIPSE_TOTAL_ELEVATION:
|
||||
return toState(moon.getEclipse().getTotalElevation(), channel);
|
||||
case CHANNEL_ID_MOON_ECLIPSE_PARTIAL:
|
||||
return toState(moon.getEclipse().getPartial(), channel);
|
||||
case CHANNEL_ID_MOON_ECLIPSE_PARTIAL_ELEVATION:
|
||||
return toState(moon.getEclipse().getPartialElevation(), channel);
|
||||
case CHANNEL_ID_MOON_DISTANCE_DATE:
|
||||
return toState(moon.getDistance().getDate(), channel);
|
||||
case CHANNEL_ID_MOON_DISTANCE_DISTANCE:
|
||||
return toState(moon.getDistance().getDistance(), channel);
|
||||
case CHANNEL_ID_MOON_PERIGEE_DATE:
|
||||
return toState(moon.getPerigee().getDate(), channel);
|
||||
case CHANNEL_ID_MOON_PERIGEE_DISTANCE:
|
||||
return toState(moon.getPerigee().getDistance(), channel);
|
||||
case CHANNEL_ID_MOON_APOGEE_DATE:
|
||||
return toState(moon.getApogee().getDate(), channel);
|
||||
case CHANNEL_ID_MOON_APOGEE_DISTANCE:
|
||||
return toState(moon.getApogee().getDistance(), channel);
|
||||
case CHANNEL_ID_MOON_POSITION_AZIMUTH:
|
||||
return toState(moon.getPosition().getAzimuth(), channel);
|
||||
case CHANNEL_ID_MOON_POSITION_ELEVATION:
|
||||
return toState(moon.getPosition().getElevation(), channel);
|
||||
case CHANNEL_ID_MOON_POSITION_SHADE_LENGTH:
|
||||
return toState(moon.getPosition().getShadeLength(), channel);
|
||||
case CHANNEL_ID_MOON_ZODIAC_SIGN:
|
||||
return toState(moon.getZodiac().getSign(), channel);
|
||||
default:
|
||||
logger.warn("Unsupported channel: {}", channel.getUID());
|
||||
}
|
||||
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getPositionalChannelIds() {
|
||||
return positionalChannelIds;
|
||||
|
||||
+204
-9
@@ -12,7 +12,9 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import java.time.Instant;
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
|
||||
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
@@ -31,12 +33,19 @@ import org.openhab.binding.astro.internal.model.Planet;
|
||||
import org.openhab.binding.astro.internal.model.Position;
|
||||
import org.openhab.binding.astro.internal.model.Radiation;
|
||||
import org.openhab.binding.astro.internal.model.Range;
|
||||
import org.openhab.binding.astro.internal.model.Season;
|
||||
import org.openhab.binding.astro.internal.model.Sun;
|
||||
import org.openhab.binding.astro.internal.model.SunPhaseName;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The SunHandler is responsible for updating calculated sun data.
|
||||
@@ -49,15 +58,17 @@ 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 volatile @Nullable Sun sun;
|
||||
private final SunCalc sunCalc;
|
||||
private final Logger logger = LoggerFactory.getLogger(SunHandler.class);
|
||||
volatile @Nullable Sun sun;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public SunHandler(Thing thing, final CronScheduler scheduler, final TimeZoneProvider timeZoneProvider,
|
||||
LocaleProvider localeProvider) {
|
||||
super(thing, scheduler, timeZoneProvider, localeProvider);
|
||||
LocaleProvider localeProvider, InstantSource instantSource) {
|
||||
super(thing, scheduler, timeZoneProvider, localeProvider, instantSource);
|
||||
sunCalc = new SunCalc(instantSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -65,12 +76,12 @@ public class SunHandler extends AstroThingHandler {
|
||||
ZoneId zoneId = timeZoneProvider.getTimeZone();
|
||||
TimeZone zone = TimeZone.getTimeZone(zoneId);
|
||||
Locale locale = localeProvider.getLocale();
|
||||
Sun sun = getSunAt(ZonedDateTime.now(zoneId));
|
||||
ZonedDateTime now = instantSource.instant().atZone(zoneId);
|
||||
Sun sun = getSunAt(now);
|
||||
Double latitude = thingConfig.latitude;
|
||||
Double longitude = thingConfig.longitude;
|
||||
Double altitude = thingConfig.altitude;
|
||||
Calendar calendar = Calendar.getInstance(zone, locale);
|
||||
ZonedDateTime now = Instant.now().atZone(zoneId);
|
||||
Calendar calendar = DateTimeUtils.calFromInstantSource(instantSource, zone, locale);
|
||||
sunCalc.setPositionalInfo(calendar, latitude != null ? latitude : 0, longitude != null ? longitude : 0,
|
||||
altitude != null ? altitude : 0, sun);
|
||||
|
||||
@@ -95,6 +106,190 @@ public class SunHandler extends AstroThingHandler {
|
||||
sun = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected State getState(Channel channel) {
|
||||
Sun sun = this.sun;
|
||||
if (sun == null) {
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
Range r;
|
||||
Season s;
|
||||
switch (channel.getUID().getId()) {
|
||||
case CHANNEL_ID_SUN_RISE_START:
|
||||
return toState(sun.getRise().getStart(), channel);
|
||||
case CHANNEL_ID_SUN_RISE_END:
|
||||
return toState(sun.getRise().getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_RISE_DURATION:
|
||||
return toState(sun.getRise().getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_SET_START:
|
||||
return toState(sun.getSet().getStart(), channel);
|
||||
case CHANNEL_ID_SUN_SET_END:
|
||||
return toState(sun.getSet().getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_SET_DURATION:
|
||||
return toState(sun.getSet().getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_NOON_START:
|
||||
r = sun.getNoon();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_NOON_END:
|
||||
r = sun.getNoon();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_NOON_DURATION:
|
||||
r = sun.getNoon();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_NIGHT_START:
|
||||
r = sun.getNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_NIGHT_END:
|
||||
r = sun.getNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_NIGHT_DURATION:
|
||||
r = sun.getNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_MORNING_NIGHT_START:
|
||||
r = sun.getMorningNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_MORNING_NIGHT_END:
|
||||
r = sun.getMorningNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_MORNING_NIGHT_DURATION:
|
||||
r = sun.getMorningNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_ASTRO_DAWN_START:
|
||||
r = sun.getAstroDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_ASTRO_DAWN_END:
|
||||
r = sun.getAstroDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_ASTRO_DAWN_DURATION:
|
||||
r = sun.getAstroDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_NAUTIC_DAWN_START:
|
||||
r = sun.getNauticDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_NAUTIC_DAWN_END:
|
||||
r = sun.getNauticDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_NAUTIC_DAWN_DURATION:
|
||||
r = sun.getNauticDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_CIVIL_DAWN_START:
|
||||
r = sun.getCivilDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_CIVIL_DAWN_END:
|
||||
r = sun.getCivilDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_CIVIL_DAWN_DURATION:
|
||||
r = sun.getCivilDawn();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_ASTRO_DUSK_START:
|
||||
r = sun.getAstroDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_ASTRO_DUSK_END:
|
||||
r = sun.getAstroDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_ASTRO_DUSK_DURATION:
|
||||
r = sun.getAstroDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_NAUTIC_DUSK_START:
|
||||
r = sun.getNauticDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_NAUTIC_DUSK_END:
|
||||
r = sun.getNauticDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_NAUTIC_DUSK_DURATION:
|
||||
r = sun.getNauticDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_CIVIL_DUSK_START:
|
||||
r = sun.getCivilDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_CIVIL_DUSK_END:
|
||||
r = sun.getCivilDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_CIVIL_DUSK_DURATION:
|
||||
r = sun.getCivilDusk();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_EVENING_NIGHT_START:
|
||||
r = sun.getEveningNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_EVENING_NIGHT_END:
|
||||
r = sun.getEveningNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_EVENING_NIGHT_DURATION:
|
||||
r = sun.getEveningNight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_DAYLIGHT_START:
|
||||
r = sun.getDaylight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getStart(), channel);
|
||||
case CHANNEL_ID_SUN_DAYLIGHT_END:
|
||||
r = sun.getDaylight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_DAYLIGHT_DURATION:
|
||||
r = sun.getDaylight();
|
||||
return r == null ? UnDefType.UNDEF : toState(r.getDuration(), channel);
|
||||
case CHANNEL_ID_SUN_POSITION_AZIMUTH:
|
||||
return toState(sun.getPosition().getAzimuth(), channel);
|
||||
case CHANNEL_ID_SUN_POSITION_ELEVATION:
|
||||
return toState(sun.getPosition().getElevation(), channel);
|
||||
case CHANNEL_ID_SUN_POSITION_SHADE_LENGTH:
|
||||
return toState(sun.getPosition().getShadeLength(), channel);
|
||||
case CHANNEL_ID_SUN_RADIATION_DIRECT:
|
||||
return toState(sun.getRadiation().getDirect(), channel);
|
||||
case CHANNEL_ID_SUN_RADIATION_DIFFUSE:
|
||||
return toState(sun.getRadiation().getDiffuse(), channel);
|
||||
case CHANNEL_ID_SUN_RADIATION_TOTAL:
|
||||
return toState(sun.getRadiation().getTotal(), channel);
|
||||
case CHANNEL_ID_SUN_ZODIAC_START:
|
||||
return toState(sun.getZodiac().getStart(), channel);
|
||||
case CHANNEL_ID_SUN_ZODIAC_END:
|
||||
return toState(sun.getZodiac().getEnd(), channel);
|
||||
case CHANNEL_ID_SUN_ZODIAC_SIGN:
|
||||
return toState(sun.getZodiac().getSign(), channel);
|
||||
case CHANNEL_ID_SUN_SEASON_NAME:
|
||||
s = sun.getSeason();
|
||||
return s == null ? UnDefType.UNDEF : toState(s.getName(), channel);
|
||||
case CHANNEL_ID_SUN_SEASON_SPRING:
|
||||
s = sun.getSeason();
|
||||
return s == null ? UnDefType.UNDEF : toState(s.getSpring(), channel);
|
||||
case CHANNEL_ID_SUN_SEASON_SUMMER:
|
||||
s = sun.getSeason();
|
||||
return s == null ? UnDefType.UNDEF : toState(s.getSummer(), channel);
|
||||
case CHANNEL_ID_SUN_SEASON_AUTUMN:
|
||||
s = sun.getSeason();
|
||||
return s == null ? UnDefType.UNDEF : toState(s.getAutumn(), channel);
|
||||
case CHANNEL_ID_SUN_SEASON_WINTER:
|
||||
s = sun.getSeason();
|
||||
return s == null ? UnDefType.UNDEF : toState(s.getWinter(), channel);
|
||||
case CHANNEL_ID_SUN_SEASON_NEXT_NAME:
|
||||
s = sun.getSeason();
|
||||
return s == null ? UnDefType.UNDEF : toState(s.getNextName(), channel);
|
||||
case CHANNEL_ID_SUN_SEASON_TIME_LEFT:
|
||||
s = sun.getSeason();
|
||||
return s == null ? UnDefType.UNDEF : toState(s.getTimeLeft(), channel);
|
||||
case CHANNEL_ID_SUN_ECLIPSE_TOTAL:
|
||||
return toState(sun.getEclipse().getTotal(), channel);
|
||||
case CHANNEL_ID_SUN_ECLIPSE_TOTAL_ELEVATION:
|
||||
return toState(sun.getEclipse().getTotalElevation(), channel);
|
||||
case CHANNEL_ID_SUN_ECLIPSE_PARTIAL:
|
||||
return toState(sun.getEclipse().getPartial(), channel);
|
||||
case CHANNEL_ID_SUN_ECLIPSE_PARTIAL_ELEVATION:
|
||||
return toState(sun.getEclipse().getPartialElevation(), channel);
|
||||
case CHANNEL_ID_SUN_ECLIPSE_RING:
|
||||
return toState(sun.getEclipse().getRing(), channel);
|
||||
case CHANNEL_ID_SUN_ECLIPSE_RING_ELEVATION:
|
||||
return toState(sun.getEclipse().getRingElevation(), channel);
|
||||
case CHANNEL_ID_SUN_PHASE_NAME:
|
||||
return toState(sun.getPhase().getName(), channel);
|
||||
case CHANNEL_ID_SUN_CIRCADIAN_BRIGHTNESS:
|
||||
return toState(sun.getCircadian().getBrightness(), channel);
|
||||
case CHANNEL_ID_SUN_CIRCADIAN_TEMPERATURE:
|
||||
return toState(sun.getCircadian().getTemperature(), channel);
|
||||
default:
|
||||
logger.warn("Unsupported channel: {}", channel.getUID());
|
||||
}
|
||||
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] getPositionalChannelIds() {
|
||||
return positionalChannelIds;
|
||||
@@ -102,7 +297,7 @@ public class SunHandler extends AstroThingHandler {
|
||||
|
||||
@Override
|
||||
protected Job getDailyJob(TimeZone zone, Locale locale) {
|
||||
return new DailyJobSun(this, zone, locale);
|
||||
return new DailyJobSun(this, zone, locale, instantSource);
|
||||
}
|
||||
|
||||
private Sun getSunAt(ZonedDateTime date) {
|
||||
|
||||
+20
-14
@@ -17,6 +17,7 @@ import static org.openhab.binding.astro.internal.job.Job.*;
|
||||
import static org.openhab.binding.astro.internal.model.SunPhaseName.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
@@ -40,18 +41,23 @@ public final class DailyJobSun extends AbstractJob {
|
||||
|
||||
private final TimeZone zone;
|
||||
private final Locale locale;
|
||||
private final InstantSource instantSource;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param handler the {@link AstroThingHandler} instance
|
||||
* @param zone the {@link TimeZone} to use.
|
||||
* @param locale the {@link Locale} to use.
|
||||
* @param instantSource the time source to use.
|
||||
* @throws IllegalArgumentException
|
||||
* if {@code thingUID} or {@code handler} is {@code null}
|
||||
*/
|
||||
public DailyJobSun(AstroThingHandler handler, TimeZone zone, Locale locale) {
|
||||
public DailyJobSun(AstroThingHandler handler, TimeZone zone, Locale locale, InstantSource instantSource) {
|
||||
super(handler);
|
||||
this.zone = zone;
|
||||
this.locale = locale;
|
||||
this.instantSource = instantSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,51 +74,51 @@ public final class DailyJobSun extends AbstractJob {
|
||||
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);
|
||||
scheduleRange(handler, sun.getRise(), EVENT_CHANNEL_ID_RISE, zone, locale, instantSource);
|
||||
scheduleRange(handler, sun.getSet(), EVENT_CHANNEL_ID_SET, zone, locale, instantSource);
|
||||
Range range = sun.getNoon();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NOON, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NOON, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getNight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NIGHT, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NIGHT, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getMorningNight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_MORNING_NIGHT, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_MORNING_NIGHT, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getAstroDawn();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_ASTRO_DAWN, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_ASTRO_DAWN, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getNauticDawn();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NAUTIC_DAWN, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NAUTIC_DAWN, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getCivilDawn();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_CIVIL_DAWN, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_CIVIL_DAWN, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getAstroDusk();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_ASTRO_DUSK, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_ASTRO_DUSK, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getNauticDusk();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NAUTIC_DUSK, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_NAUTIC_DUSK, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getCivilDusk();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_CIVIL_DUSK, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_CIVIL_DUSK, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getEveningNight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_EVENING_NIGHT, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_EVENING_NIGHT, zone, locale, instantSource);
|
||||
}
|
||||
range = sun.getDaylight();
|
||||
if (range != null) {
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_DAYLIGHT, zone, locale);
|
||||
scheduleRange(handler, range, EVENT_CHANNEL_ID_DAYLIGHT, zone, locale, instantSource);
|
||||
}
|
||||
|
||||
Eclipse eclipse = sun.getEclipse();
|
||||
|
||||
+9
-4
@@ -18,6 +18,7 @@ import static org.openhab.binding.astro.internal.util.DateTimeUtils.*;
|
||||
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZoneId;
|
||||
import java.util.Calendar;
|
||||
import java.util.List;
|
||||
@@ -29,6 +30,7 @@ import org.openhab.binding.astro.internal.config.AstroChannelConfig;
|
||||
import org.openhab.binding.astro.internal.handler.AstroThingHandler;
|
||||
import org.openhab.binding.astro.internal.model.Range;
|
||||
import org.openhab.binding.astro.internal.model.SunPhaseName;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
import org.openhab.core.scheduler.SchedulerRunnable;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.slf4j.Logger;
|
||||
@@ -56,6 +58,7 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||
*/
|
||||
static void schedule(AstroThingHandler astroHandler, Job job, Calendar eventAt, TimeZone zone, Locale locale) {
|
||||
try {
|
||||
// Don't use InstantSource here, because we always want to schedule relative to the system clock
|
||||
Calendar today = Calendar.getInstance(zone, locale);
|
||||
boolean sameDay = isSameDay(eventAt, today);
|
||||
if (sameDay && isTimeGreaterEquals(eventAt, today)) {
|
||||
@@ -81,6 +84,7 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||
* @param zone the configured time zone
|
||||
*/
|
||||
static void schedule(AstroThingHandler astroHandler, Job job, Instant eventAt, ZoneId zone) {
|
||||
// Don't use InstantSource here, because we always want to schedule relative to the system clock
|
||||
Instant now = Instant.now();
|
||||
boolean sameDay = isSameDay(eventAt.atZone(zone), now.atZone(zone));
|
||||
if (sameDay && !eventAt.isBefore(now)) {
|
||||
@@ -196,14 +200,14 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||
* @param channelId the channel ID
|
||||
*/
|
||||
static void scheduleRange(AstroThingHandler astroHandler, Range range, String channelId, TimeZone zone,
|
||||
Locale locale) {
|
||||
Locale locale, InstantSource instantSource) {
|
||||
final Channel channel = astroHandler.getThing().getChannel(channelId);
|
||||
if (channel == null) {
|
||||
LOGGER.warn("Cannot find channel '{}' for thing '{}'.", channelId, astroHandler.getThing().getUID());
|
||||
return;
|
||||
}
|
||||
AstroChannelConfig config = channel.getConfiguration().as(AstroChannelConfig.class);
|
||||
Range adjustedRange = adjustRangeToConfig(range, config, zone, locale);
|
||||
Range adjustedRange = adjustRangeToConfig(range, config, zone, locale, instantSource);
|
||||
|
||||
Calendar start = adjustedRange.getStart();
|
||||
Calendar end = adjustedRange.getEnd();
|
||||
@@ -217,14 +221,15 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||
scheduleEvent(astroHandler, end, EVENT_END, channelId, true, zone, locale);
|
||||
}
|
||||
|
||||
static Range adjustRangeToConfig(Range range, AstroChannelConfig config, TimeZone zone, Locale locale) {
|
||||
static Range adjustRangeToConfig(Range range, AstroChannelConfig config, TimeZone zone, Locale locale,
|
||||
InstantSource instantSource) {
|
||||
Calendar start = range.getStart();
|
||||
Calendar end = range.getEnd();
|
||||
|
||||
if (config.forceEvent) {
|
||||
Calendar reference = start != null ? start : end;
|
||||
if (reference == null) {
|
||||
reference = Calendar.getInstance(zone, locale);
|
||||
reference = DateTimeUtils.calFromInstantSource(instantSource, zone, locale);
|
||||
}
|
||||
if (start == null) {
|
||||
start = getAdjustedEarliest(truncateToMidnight(reference), config);
|
||||
|
||||
+9
-5
@@ -14,6 +14,7 @@ package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -51,12 +52,15 @@ public class Season {
|
||||
|
||||
private final List<LocalSeason> seasons = new ArrayList<>(5);
|
||||
private final int year;
|
||||
private final InstantSource instantSource;
|
||||
|
||||
public Season(double latitude, boolean useMeteorologicalSeason, TimeZone zone, Instant... equiSols) {
|
||||
public Season(double latitude, boolean useMeteorologicalSeason, TimeZone zone, InstantSource instantSource,
|
||||
Instant... equiSols) {
|
||||
// Expect to receive last of previous year, all from current year, first of next year
|
||||
if (equiSols.length != SeasonName.values().length + 2) {
|
||||
throw new IllegalArgumentException("Incorrect number of seasons provided");
|
||||
}
|
||||
this.instantSource = instantSource;
|
||||
var hemisphere = Hemisphere.getHemisphere(latitude);
|
||||
List<Instant> moments = Arrays.stream(equiSols).sorted()
|
||||
.map(i -> useMeteorologicalSeason ? DateTimeUtils.atMidnightOfFirstMonthDay(i, zone) : i).toList();
|
||||
@@ -115,28 +119,28 @@ public class Season {
|
||||
* Returns the current season name.
|
||||
*/
|
||||
public SeasonName getName() {
|
||||
return getSeason(Instant.now()).name;
|
||||
return getSeason(instantSource.instant()).name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next season.
|
||||
*/
|
||||
public Instant getNextSeason() {
|
||||
return getSeason(Instant.now()).endsOn;
|
||||
return getSeason(instantSource.instant()).endsOn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next season name.
|
||||
*/
|
||||
public SeasonName getNextName() {
|
||||
return getSeason(Instant.now()).name.next();
|
||||
return getSeason(instantSource.instant()).name.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time left for current season
|
||||
*/
|
||||
public QuantityType<Time> getTimeLeft() {
|
||||
var now = Instant.now();
|
||||
var now = instantSource.instant();
|
||||
var timeLeft = Duration.between(now, getSeason(now).endsOn);
|
||||
|
||||
return new QuantityType<>(timeLeft.toDays(), Units.DAY);
|
||||
|
||||
+22
-4
@@ -13,6 +13,7 @@
|
||||
package org.openhab.binding.astro.internal.util;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Calendar;
|
||||
@@ -217,8 +218,9 @@ public class DateTimeUtils {
|
||||
/**
|
||||
* Returns the next Calendar from today.
|
||||
*/
|
||||
public static Calendar getNextFromToday(TimeZone zone, Locale locale, Calendar... calendars) {
|
||||
Calendar now = Calendar.getInstance(zone, locale);
|
||||
public static Calendar getNextFromToday(TimeZone zone, Locale locale, InstantSource instantSource,
|
||||
Calendar... calendars) {
|
||||
Calendar now = calFromInstantSource(instantSource, zone, locale);
|
||||
Calendar result = getNext(now, calendars);
|
||||
return result == null ? now : result;
|
||||
}
|
||||
@@ -400,8 +402,9 @@ public class DateTimeUtils {
|
||||
return (jd - JD_J2000) / JULIAN_CENTURY_DAYS;
|
||||
}
|
||||
|
||||
public static Calendar createCalendarForToday(int hour, int minute, TimeZone zone, Locale locale) {
|
||||
return DateTimeUtils.adjustTime(Calendar.getInstance(zone, locale), hour * 60 + minute);
|
||||
public static Calendar createCalendarForToday(int hour, int minute, TimeZone zone, Locale locale,
|
||||
InstantSource instantSource) {
|
||||
return adjustTime(calFromInstantSource(instantSource, zone, locale), hour * 60 + minute);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -450,4 +453,19 @@ public class DateTimeUtils {
|
||||
public static Instant atMidnightOfFirstMonthDay(Instant instant, TimeZone zone) {
|
||||
return instant.atZone(zone.toZoneId()).withDayOfMonth(1).truncatedTo(ChronoUnit.DAYS).toInstant();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link Calendar} instance with the specified time zone and locale, with the specified
|
||||
* {@link InstantSource} as the time source.
|
||||
*
|
||||
* @param instantSource the time source.
|
||||
* @param zone the {@link TimeZone} to use.
|
||||
* @param locale the {@link Locale} to use.
|
||||
* @return The new {@link Calendar} instance.
|
||||
*/
|
||||
public static Calendar calFromInstantSource(InstantSource instantSource, TimeZone zone, Locale locale) {
|
||||
Calendar result = Calendar.getInstance(zone, locale);
|
||||
result.setTimeInMillis(instantSource.millis());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
-114
@@ -1,114 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.util;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Instant;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.config.AstroChannelConfig;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* Methods to get the value from a property of an object.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
* @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
|
||||
* @author Christoph Weitkamp - Introduced UoM
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class PropertyUtils {
|
||||
|
||||
/** Constructor */
|
||||
private PropertyUtils() {
|
||||
throw new IllegalAccessError("Non-instantiable");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state of the channel.
|
||||
*/
|
||||
public static State getState(ChannelUID channelUID, AstroChannelConfig config, Object instance, TimeZone zone)
|
||||
throws Exception {
|
||||
Object value = getPropertyValue(channelUID, instance);
|
||||
if (value == null) {
|
||||
return UnDefType.UNDEF;
|
||||
} else if (value instanceof State state) {
|
||||
return state;
|
||||
} else if (value instanceof Calendar cal) {
|
||||
GregorianCalendar gregorianCal = (GregorianCalendar) DateTimeUtils.applyConfig(cal, config);
|
||||
cal.setTimeZone(zone);
|
||||
ZonedDateTime zoned = gregorianCal.toZonedDateTime().withFixedOffsetZone();
|
||||
return new DateTimeType(zoned);
|
||||
} else if (value instanceof Instant instant) {
|
||||
Instant configuredInstant = DateTimeUtils.applyConfig(instant, config);
|
||||
return new DateTimeType(configuredInstant.atZone(zone.toZoneId()).withFixedOffsetZone());
|
||||
} else if (value instanceof Number) {
|
||||
BigDecimal decimalValue = new BigDecimal(value.toString()).setScale(2, RoundingMode.HALF_UP);
|
||||
return new DecimalType(decimalValue);
|
||||
} else if (value instanceof String || value instanceof Enum) {
|
||||
return new StringType(value.toString());
|
||||
} else {
|
||||
throw new IllegalStateException("Unsupported value type " + value.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the property value from the object instance, nested properties are possible. If the propertyName is for
|
||||
* example rise.start, the methods getRise().getStart() are called.
|
||||
*/
|
||||
private static @Nullable Object getPropertyValue(ChannelUID channelUID, Object instance) throws Exception {
|
||||
ArrayList<String> properties = new ArrayList<>(List.of(channelUID.getId().split("#")));
|
||||
return getPropertyValue(instance, properties);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates through the nested properties and returns the getter value.
|
||||
*/
|
||||
@SuppressWarnings("all")
|
||||
private static @Nullable Object getPropertyValue(Object instance, List<String> properties) throws Exception {
|
||||
String propertyName = properties.remove(0);
|
||||
Method m = instance.getClass().getMethod(toGetterString(propertyName), null);
|
||||
Object result = m.invoke(instance, (Object[]) null);
|
||||
if (!properties.isEmpty()) {
|
||||
Objects.requireNonNull(result);
|
||||
return getPropertyValue(result, properties);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the string to a getter property.
|
||||
*/
|
||||
private static String toGetterString(String str) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("get");
|
||||
sb.append(Character.toTitleCase(str.charAt(0)));
|
||||
sb.append(str.substring(1));
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.test.cases;
|
||||
package org.openhab.binding.astro.internal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
@@ -20,7 +20,7 @@ import java.math.BigDecimal;
|
||||
* @author Svilen Valkanov - Initial contribution
|
||||
* @author Christoph Weitkamp - Migrated tests to pure Java
|
||||
*/
|
||||
public final class AstroBindingTestsData {
|
||||
public final class CommonTestConstants {
|
||||
|
||||
public static final String TEST_SUN_THING_ID = "testSunThingId";
|
||||
public static final String TEST_MOON_THING_ID = "testMoonThingId";
|
||||
+3
-1
@@ -14,6 +14,8 @@ package org.openhab.binding.astro.internal.calc;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
@@ -54,7 +56,7 @@ public class MoonCalcTest {
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
moonCalc = new MoonCalc();
|
||||
moonCalc = new MoonCalc(InstantSource.fixed(Instant.ofEpochMilli(1645671600000L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+9
-7
@@ -15,6 +15,7 @@ package org.openhab.binding.astro.internal.calc;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
@@ -55,12 +56,13 @@ public class SeasonCalcTest {
|
||||
AMSTERDAM_TZ);
|
||||
private static final double AMSTERDAM_LONGITUDE = 4.8978293;
|
||||
private static final double AMSTERDAM_ALTITUDE = 0.0;
|
||||
private static final InstantSource INSTANT_SOURCE = InstantSource.fixed(Instant.ofEpochMilli(1645671600000L));
|
||||
|
||||
private @Nullable SunCalc sunCalc;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
sunCalc = new SunCalc();
|
||||
sunCalc = new SunCalc(INSTANT_SOURCE);
|
||||
}
|
||||
|
||||
/***
|
||||
@@ -128,23 +130,23 @@ public class SeasonCalcTest {
|
||||
|
||||
@Test
|
||||
public void testGetSeasonAmsterdam() {
|
||||
final Season season = SeasonCalc.calculate(2020, AMSTERDAM_LATITUDE, true, AMSTERDAM_TZ);
|
||||
final Season season = SeasonCalc.calculate(2020, AMSTERDAM_LATITUDE, true, AMSTERDAM_TZ, INSTANT_SOURCE);
|
||||
|
||||
assertNextSeason(season.getSpring(), 2020, JAN_20_2020, season, AMSTERDAM_TZ);
|
||||
assertNextSeason(season.getSummer(), 2020, MAY_20_2020, season, AMSTERDAM_TZ);
|
||||
assertNextSeason(season.getWinter(), 2020, SEPT_20_2020, season, AMSTERDAM_TZ);
|
||||
assertNextSeason(SeasonCalc.calculate(2021, AMSTERDAM_LATITUDE, true, AMSTERDAM_TZ).getSpring(), 2021,
|
||||
DEC_10_2020, season, AMSTERDAM_TZ);
|
||||
assertNextSeason(SeasonCalc.calculate(2021, AMSTERDAM_LATITUDE, true, AMSTERDAM_TZ, INSTANT_SOURCE).getSpring(),
|
||||
2021, DEC_10_2020, season, AMSTERDAM_TZ);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSeasonSydney() {
|
||||
final Season season = SeasonCalc.calculate(2020, SYDNEY_LATITUDE, true, SYDNEY_TZ);
|
||||
final Season season = SeasonCalc.calculate(2020, SYDNEY_LATITUDE, true, SYDNEY_TZ, INSTANT_SOURCE);
|
||||
|
||||
assertNextSeason(season.getAutumn(), 2020, JAN_20_2020, season, SYDNEY_TZ);
|
||||
assertNextSeason(season.getWinter(), 2020, MAY_20_2020, season, SYDNEY_TZ);
|
||||
assertNextSeason(season.getSummer(), 2020, SEPT_20_2020, season, SYDNEY_TZ);
|
||||
assertNextSeason(SeasonCalc.calculate(2021, SYDNEY_LATITUDE, true, SYDNEY_TZ).getAutumn(), 2021, DEC_10_2020,
|
||||
season, SYDNEY_TZ);
|
||||
assertNextSeason(SeasonCalc.calculate(2021, SYDNEY_LATITUDE, true, SYDNEY_TZ, INSTANT_SOURCE).getAutumn(), 2021,
|
||||
DEC_10_2020, season, SYDNEY_TZ);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -14,6 +14,8 @@ package org.openhab.binding.astro.internal.calc;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
@@ -61,7 +63,7 @@ public class SunCalcTest {
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
sunCalc = new SunCalc();
|
||||
sunCalc = new SunCalc(InstantSource.fixed(Instant.ofEpochMilli(1645671600000L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+3
-1
@@ -14,6 +14,8 @@ package org.openhab.binding.astro.internal.calc.zodiac;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
@@ -53,7 +55,7 @@ public class MoonZodiacCalcTest {
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
moonCalc = new MoonCalc();
|
||||
moonCalc = new MoonCalc(InstantSource.fixed(Instant.ofEpochMilli(1645671600000L)));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+7
-6
@@ -10,18 +10,18 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.handler.test;
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.THING_TYPE_SUN;
|
||||
import static org.openhab.binding.astro.test.cases.AstroBindingTestsData.*;
|
||||
import static org.openhab.binding.astro.internal.CommonTestConstants.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZoneId;
|
||||
|
||||
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.binding.astro.internal.model.Sun;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
@@ -45,7 +45,7 @@ import org.openhab.core.types.State;
|
||||
* @author Svilen Valkanov - Reworked to plain unit tests
|
||||
* @author Christoph Weitkamp - Migrated tests to pure Java
|
||||
*/
|
||||
public class AstroCommandTest {
|
||||
public class CommandTest {
|
||||
|
||||
@Test
|
||||
public void testRefreshCommandUpdatesTheStateOfTheChannels() {
|
||||
@@ -67,7 +67,8 @@ public class AstroCommandTest {
|
||||
TimeZoneProvider timeZoneProvider = mock(TimeZoneProvider.class);
|
||||
LocaleProvider localeProvider = mock(LocaleProvider.class);
|
||||
when(timeZoneProvider.getTimeZone()).thenReturn(ZoneId.systemDefault());
|
||||
AstroThingHandler sunHandler = spy(new SunHandler(thing, cronScheduler, timeZoneProvider, localeProvider));
|
||||
AstroThingHandler sunHandler = spy(new SunHandler(thing, cronScheduler, timeZoneProvider, localeProvider,
|
||||
InstantSource.fixed(Instant.ofEpochMilli(1645671600000L))));
|
||||
|
||||
// Required from the AstroThingHandler to send the status update
|
||||
doReturn(true).when(callback).isChannelLinked(eq(channelUID));
|
||||
+36
-37
@@ -10,20 +10,19 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.test.cases;
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import static org.openhab.binding.astro.test.cases.AstroBindingTestsData.*;
|
||||
import static org.openhab.binding.astro.internal.CommonTestConstants.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.openhab.binding.astro.test.AstroStateTest;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
|
||||
/**
|
||||
* Test cases used in the {@link AstroStateTest}
|
||||
* Test cases used in the {@link StateTest}
|
||||
*
|
||||
* @author Petar Valchev - Initial contribution
|
||||
* @author Svilen Valakanov - Added test data from
|
||||
@@ -32,7 +31,7 @@ import org.openhab.core.library.unit.Units;
|
||||
* @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
|
||||
* @author Christoph Weitkamp - Introduced UoM and migrated tests to pure Java
|
||||
*/
|
||||
public final class AstroParametrizedTestCases {
|
||||
public final class ParametrizedStateTestCases {
|
||||
|
||||
public static final double TEST_LATITUDE = 22.4343;
|
||||
public static final double TEST_LONGITUDE = 54.3225;
|
||||
@@ -42,38 +41,38 @@ public final class AstroParametrizedTestCases {
|
||||
|
||||
public Object[][] cases = new Object[42][3];
|
||||
|
||||
public AstroParametrizedTestCases() {
|
||||
public ParametrizedStateTestCases() {
|
||||
cases[0][0] = TEST_SUN_THING_ID;
|
||||
cases[0][1] = "rise#start";
|
||||
cases[0][2] = new DateTimeType("2016-02-29T05:46:00+03:00");
|
||||
cases[0][2] = new DateTimeType("2016-02-29T05:46:07+03:00");
|
||||
|
||||
cases[1][0] = TEST_SUN_THING_ID;
|
||||
cases[1][1] = "rise#end";
|
||||
cases[1][2] = new DateTimeType("2016-02-29T05:48:00+03:00");
|
||||
cases[1][2] = new DateTimeType("2016-02-29T05:48:26+03:00");
|
||||
|
||||
cases[2][0] = TEST_SUN_THING_ID;
|
||||
cases[2][1] = "rise#duration";
|
||||
cases[2][2] = new QuantityType<>(2, Units.MINUTE);
|
||||
cases[2][2] = new QuantityType<>(2.32, Units.MINUTE);
|
||||
|
||||
cases[3][0] = TEST_SUN_THING_ID;
|
||||
cases[3][1] = "set#start";
|
||||
cases[3][2] = new DateTimeType("2016-02-29T17:25:00+03:00");
|
||||
cases[3][2] = new DateTimeType("2016-02-29T17:24:56+03:00");
|
||||
|
||||
cases[4][0] = TEST_SUN_THING_ID;
|
||||
cases[4][1] = "set#end";
|
||||
cases[4][2] = new DateTimeType("2016-02-29T17:27:00+03:00");
|
||||
cases[4][2] = new DateTimeType("2016-02-29T17:27:15+03:00");
|
||||
|
||||
cases[5][0] = TEST_SUN_THING_ID;
|
||||
cases[5][1] = "set#duration";
|
||||
cases[5][2] = new QuantityType<>(2, Units.MINUTE);
|
||||
cases[5][2] = new QuantityType<>(2.32, Units.MINUTE);
|
||||
|
||||
cases[6][0] = TEST_SUN_THING_ID;
|
||||
cases[6][1] = "noon#start";
|
||||
cases[6][2] = new DateTimeType("2016-02-29T11:37:00+03:00");
|
||||
cases[6][2] = new DateTimeType("2016-02-29T11:36:41+03:00");
|
||||
|
||||
cases[7][0] = TEST_SUN_THING_ID;
|
||||
cases[7][1] = "noon#end";
|
||||
cases[7][2] = new DateTimeType("2016-02-29T11:38:00+03:00");
|
||||
cases[7][2] = new DateTimeType("2016-02-29T11:37:41+03:00");
|
||||
|
||||
cases[8][0] = TEST_SUN_THING_ID;
|
||||
cases[8][1] = "noon#duration";
|
||||
@@ -81,11 +80,11 @@ public final class AstroParametrizedTestCases {
|
||||
|
||||
cases[9][0] = TEST_SUN_THING_ID;
|
||||
cases[9][1] = "night#start";
|
||||
cases[9][2] = new DateTimeType("2016-02-29T18:42:00+03:00");
|
||||
cases[9][2] = new DateTimeType("2016-02-29T18:41:51+03:00");
|
||||
|
||||
cases[10][0] = TEST_SUN_THING_ID;
|
||||
cases[10][1] = "night#end";
|
||||
cases[10][2] = new DateTimeType("2016-03-01T04:31:00+03:00");
|
||||
cases[10][2] = new DateTimeType("2016-03-01T04:30:44+03:00");
|
||||
|
||||
cases[11][0] = TEST_SUN_THING_ID;
|
||||
cases[11][1] = "night#duration";
|
||||
@@ -97,7 +96,7 @@ public final class AstroParametrizedTestCases {
|
||||
|
||||
cases[13][0] = TEST_SUN_THING_ID;
|
||||
cases[13][1] = "morningNight#end";
|
||||
cases[13][2] = new DateTimeType("2016-02-29T04:32:00+03:00");
|
||||
cases[13][2] = new DateTimeType("2016-02-29T04:31:31+03:00");
|
||||
|
||||
cases[14][0] = TEST_SUN_THING_ID;
|
||||
cases[14][1] = "morningNight#duration";
|
||||
@@ -105,11 +104,11 @@ public final class AstroParametrizedTestCases {
|
||||
|
||||
cases[15][0] = TEST_SUN_THING_ID;
|
||||
cases[15][1] = "astroDawn#start";
|
||||
cases[15][2] = new DateTimeType("2016-02-29T04:32:00+03:00");
|
||||
cases[15][2] = new DateTimeType("2016-02-29T04:31:31+03:00");
|
||||
|
||||
cases[16][0] = TEST_SUN_THING_ID;
|
||||
cases[16][1] = "astroDawn#end";
|
||||
cases[16][2] = new DateTimeType("2016-02-29T04:58:00+03:00");
|
||||
cases[16][2] = new DateTimeType("2016-02-29T04:57:31+03:00");
|
||||
|
||||
cases[17][0] = TEST_SUN_THING_ID;
|
||||
cases[17][1] = "astroDawn#duration";
|
||||
@@ -117,35 +116,35 @@ public final class AstroParametrizedTestCases {
|
||||
|
||||
cases[18][0] = TEST_SUN_THING_ID;
|
||||
cases[18][1] = "nauticDawn#start";
|
||||
cases[18][2] = new DateTimeType("2016-02-29T04:58:00+03:00");
|
||||
cases[18][2] = new DateTimeType("2016-02-29T04:57:31+03:00");
|
||||
|
||||
cases[19][0] = TEST_SUN_THING_ID;
|
||||
cases[19][1] = "nauticDawn#end";
|
||||
cases[19][2] = new DateTimeType("2016-02-29T05:24:00+03:00");
|
||||
cases[19][2] = new DateTimeType("2016-02-29T05:23:34+03:00");
|
||||
|
||||
cases[20][0] = TEST_SUN_THING_ID;
|
||||
cases[20][1] = "nauticDawn#duration";
|
||||
cases[20][2] = new QuantityType<>(26, Units.MINUTE);
|
||||
cases[20][2] = new QuantityType<>(26.1, Units.MINUTE);
|
||||
|
||||
cases[21][0] = TEST_SUN_THING_ID;
|
||||
cases[21][1] = "civilDawn#start";
|
||||
cases[21][2] = new DateTimeType("2016-02-29T05:24:00+03:00");
|
||||
cases[21][2] = new DateTimeType("2016-02-29T05:23:34+03:00");
|
||||
|
||||
cases[22][0] = TEST_SUN_THING_ID;
|
||||
cases[22][1] = "civilDawn#end";
|
||||
cases[22][2] = new DateTimeType("2016-02-29T05:46:00+03:00");
|
||||
cases[22][2] = new DateTimeType("2016-02-29T05:46:07+03:00");
|
||||
|
||||
cases[23][0] = TEST_SUN_THING_ID;
|
||||
cases[23][1] = "civilDawn#duration";
|
||||
cases[23][2] = new QuantityType<>(22, Units.MINUTE);
|
||||
cases[23][2] = new QuantityType<>(22.5, Units.MINUTE);
|
||||
|
||||
cases[24][0] = TEST_SUN_THING_ID;
|
||||
cases[24][1] = "astroDusk#start";
|
||||
cases[24][2] = new DateTimeType("2016-02-29T18:16:00+03:00");
|
||||
cases[24][2] = new DateTimeType("2016-02-29T18:15:52+03:00");
|
||||
|
||||
cases[25][0] = TEST_SUN_THING_ID;
|
||||
cases[25][1] = "astroDusk#end";
|
||||
cases[25][2] = new DateTimeType("2016-02-29T18:42:00+03:00");
|
||||
cases[25][2] = new DateTimeType("2016-02-29T18:41:51+03:00");
|
||||
|
||||
cases[26][0] = TEST_SUN_THING_ID;
|
||||
cases[26][1] = "astroDusk#duration";
|
||||
@@ -153,31 +152,31 @@ public final class AstroParametrizedTestCases {
|
||||
|
||||
cases[27][0] = TEST_SUN_THING_ID;
|
||||
cases[27][1] = "nauticDusk#start";
|
||||
cases[27][2] = new DateTimeType("2016-02-29T17:50:00+03:00");
|
||||
cases[27][2] = new DateTimeType("2016-02-29T17:49:48+03:00");
|
||||
|
||||
cases[28][0] = TEST_SUN_THING_ID;
|
||||
cases[28][1] = "nauticDusk#end";
|
||||
cases[28][2] = new DateTimeType("2016-02-29T18:16:00+03:00");
|
||||
cases[28][2] = new DateTimeType("2016-02-29T18:15:52+03:00");
|
||||
|
||||
cases[29][0] = TEST_SUN_THING_ID;
|
||||
cases[29][1] = "nauticDusk#duration";
|
||||
cases[29][2] = new QuantityType<>(26, Units.MINUTE);
|
||||
cases[29][2] = new QuantityType<>(26.1, Units.MINUTE);
|
||||
|
||||
cases[30][0] = TEST_SUN_THING_ID;
|
||||
cases[30][1] = "civilDusk#start";
|
||||
cases[30][2] = new DateTimeType("2016-02-29T17:27:00+03:00");
|
||||
cases[30][2] = new DateTimeType("2016-02-29T17:27:15+03:00");
|
||||
|
||||
cases[31][0] = TEST_SUN_THING_ID;
|
||||
cases[31][1] = "civilDusk#end";
|
||||
cases[31][2] = new DateTimeType("2016-02-29T17:50:00+03:00");
|
||||
cases[31][2] = new DateTimeType("2016-02-29T17:49:48+03:00");
|
||||
|
||||
cases[32][0] = TEST_SUN_THING_ID;
|
||||
cases[32][1] = "civilDusk#duration";
|
||||
cases[32][2] = new QuantityType<>(23, Units.MINUTE);
|
||||
cases[32][2] = new QuantityType<>(22.5, Units.MINUTE);
|
||||
|
||||
cases[33][0] = TEST_SUN_THING_ID;
|
||||
cases[33][1] = "eveningNight#start";
|
||||
cases[33][2] = new DateTimeType("2016-02-29T18:42:00+03:00");
|
||||
cases[33][2] = new DateTimeType("2016-02-29T18:41:51+03:00");
|
||||
|
||||
cases[34][0] = TEST_SUN_THING_ID;
|
||||
cases[34][1] = "eveningNight#end";
|
||||
@@ -189,15 +188,15 @@ public final class AstroParametrizedTestCases {
|
||||
|
||||
cases[36][0] = TEST_SUN_THING_ID;
|
||||
cases[36][1] = "daylight#start";
|
||||
cases[36][2] = new DateTimeType("2016-02-29T05:48:00+03:00");
|
||||
cases[36][2] = new DateTimeType("2016-02-29T05:48:26+03:00");
|
||||
|
||||
cases[37][0] = TEST_SUN_THING_ID;
|
||||
cases[37][1] = "daylight#end";
|
||||
cases[37][2] = new DateTimeType("2016-02-29T17:25:00+03:00");
|
||||
cases[37][2] = new DateTimeType("2016-02-29T17:24:56+03:00");
|
||||
|
||||
cases[38][0] = TEST_SUN_THING_ID;
|
||||
cases[38][1] = "daylight#duration";
|
||||
cases[38][2] = new QuantityType<>(697, Units.MINUTE);
|
||||
cases[38][2] = new QuantityType<>(696, Units.MINUTE);
|
||||
|
||||
cases[39][0] = TEST_MOON_THING_ID;
|
||||
cases[39][1] = "rise#start";
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
|
||||
import static org.openhab.binding.astro.internal.CommonTestConstants.*;
|
||||
import static org.openhab.binding.astro.internal.handler.ParametrizedStateTestCases.*;
|
||||
|
||||
import java.math.MathContext;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.measure.Unit;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.DateTimeType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* Tests for the Astro Channels state
|
||||
*
|
||||
* @see ParametrizedStateTestCases
|
||||
* @author Petar Valchev - Initial contribution
|
||||
* @author Svilen Valkanov - Reworked to plain unit tests
|
||||
* @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
|
||||
* @author Christoph Weitkamp - Migrated tests to pure Java
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
public class StateTest {
|
||||
|
||||
// These test result timestamps are adapted for the +03:00 time zone
|
||||
private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Asia/Baghdad");
|
||||
private static final ZoneId ZONE_ID = TIME_ZONE.toZoneId();
|
||||
private static final Locale LOCALE = Locale.of("ar", "iq");
|
||||
|
||||
private @Mock TimeZoneProvider timeZoneProvider;
|
||||
private @Mock Thing thing;
|
||||
private @Mock CronScheduler scheduler;
|
||||
private @Mock LocaleProvider localeProvider;
|
||||
private @Mock Channel channel;
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
when(timeZoneProvider.getTimeZone()).thenReturn(TIME_ZONE.toZoneId());
|
||||
when(localeProvider.getLocale()).thenReturn(LOCALE);
|
||||
Configuration c = new Configuration(
|
||||
Map.of("geolocation", Double.toString(TEST_LATITUDE) + ',' + Double.toString(TEST_LONGITUDE),
|
||||
"latitude", Double.valueOf(TEST_LATITUDE), "longitude", Double.valueOf(TEST_LONGITUDE),
|
||||
INTERVAL_PROPERTY, INTERVAL_DEFAULT_VALUE));
|
||||
when(thing.getConfiguration()).thenReturn(c);
|
||||
}
|
||||
|
||||
public static List<Object[]> data() {
|
||||
ParametrizedStateTestCases cases = new ParametrizedStateTestCases();
|
||||
return cases.getCases();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testParametrized(String thingID, String channelId, State expectedState) throws Exception {
|
||||
assertStateUpdate(thingID, channelId, expectedState);
|
||||
}
|
||||
|
||||
private void assertStateUpdate(String thingID, String channelId, State expectedState) throws Exception {
|
||||
AstroThingHandler handler = getHandler(thingID);
|
||||
|
||||
when(channel.getUID()).thenReturn(new ChannelUID(getThingUID(thingID), channelId));
|
||||
when(channel.getConfiguration()).thenReturn(new Configuration());
|
||||
|
||||
State state = handler.getState(channel);
|
||||
if (state instanceof DateTimeType dateTime) {
|
||||
// Truncate to second
|
||||
state = new DateTimeType(Instant.ofEpochMilli((dateTime.getInstant().toEpochMilli() / 1000L) * 1000L));
|
||||
} else if (state instanceof QuantityType quantity) {
|
||||
Unit<?> unit = quantity.getUnit();
|
||||
state = new QuantityType<>(quantity.toBigDecimal().round(new MathContext(3, RoundingMode.HALF_UP)), unit);
|
||||
}
|
||||
|
||||
assertEquals(expectedState, state);
|
||||
handler.dispose();
|
||||
}
|
||||
|
||||
private ThingUID getThingUID(String thingID) {
|
||||
switch (thingID) {
|
||||
case (TEST_SUN_THING_ID):
|
||||
return new ThingUID(THING_TYPE_SUN, thingID);
|
||||
case (TEST_MOON_THING_ID):
|
||||
return new ThingUID(THING_TYPE_MOON, thingID);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private AstroThingHandler getHandler(String thingID) {
|
||||
LocalDateTime time = LocalDateTime.of(TEST_YEAR, TEST_MONTH, TEST_DAY, 0, 0);
|
||||
ZonedDateTime zonedTime = ZonedDateTime.ofLocal(time, ZONE_ID, null);
|
||||
InstantSource instantSource = InstantSource.fixed(zonedTime.toInstant());
|
||||
when(thing.getUID()).thenReturn(getThingUID(thingID));
|
||||
switch (thingID) {
|
||||
case (TEST_SUN_THING_ID):
|
||||
SunHandler sunHandler = new SunHandler(thing, scheduler, timeZoneProvider, localeProvider,
|
||||
instantSource);
|
||||
sunHandler.initialize();
|
||||
sunHandler.publishDailyInfo();
|
||||
return sunHandler;
|
||||
case (TEST_MOON_THING_ID):
|
||||
MoonHandler moonHandler = new MoonHandler(thing, scheduler, timeZoneProvider, localeProvider,
|
||||
instantSource);
|
||||
moonHandler.initialize();
|
||||
moonHandler.publishDailyInfo();
|
||||
return moonHandler;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+48
-17
@@ -10,21 +10,36 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.openhab.binding.astro.internal.config.AstroChannelConfig;
|
||||
import org.openhab.binding.astro.internal.util.PropertyUtils;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
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.library.types.StringType;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.Thing;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/***
|
||||
@@ -35,18 +50,35 @@ import org.openhab.core.types.UnDefType;
|
||||
* @see <a href="https://github.com/openhab/openhab-addons/issues/5006">[astro]
|
||||
* Sun Phase returns UNDEF</a>
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
@NonNullByDefault
|
||||
public class SunTest {
|
||||
|
||||
private @Nullable Sun sun;
|
||||
private @Nullable AstroChannelConfig config;
|
||||
|
||||
private @Mock @NonNullByDefault({}) TimeZoneProvider timeZoneProvider;
|
||||
private @Mock @NonNullByDefault({}) Thing thing;
|
||||
private @Mock @NonNullByDefault({}) CronScheduler scheduler;
|
||||
private @Mock @NonNullByDefault({}) LocaleProvider localeProvider;
|
||||
private @Mock @NonNullByDefault({}) Channel channel;
|
||||
|
||||
private @NonNullByDefault({}) SunHandler handler;
|
||||
|
||||
private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Asia/Gaza");
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
sun = new Sun();
|
||||
config = new AstroChannelConfig();
|
||||
when(timeZoneProvider.getTimeZone()).thenReturn(TIME_ZONE.toZoneId());
|
||||
when(localeProvider.getLocale()).thenReturn(Locale.ROOT);
|
||||
handler = new SunHandler(thing, scheduler, timeZoneProvider, localeProvider,
|
||||
InstantSource.fixed(Instant.ofEpochMilli(1645671600000L)));
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
public void dispose() {
|
||||
handler.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,28 +86,27 @@ public class SunTest {
|
||||
Sun sun = this.sun;
|
||||
assertNotNull(sun);
|
||||
assertNotNull(sun.getPhase());
|
||||
assertEquals(UnDefType.UNDEF, PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"),
|
||||
Objects.requireNonNull(config), sun, TIME_ZONE));
|
||||
|
||||
when(channel.getUID()).thenReturn(new ChannelUID("astro:sun:home:phase#name"));
|
||||
assertEquals(UnDefType.UNDEF, handler.getState(channel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateWhenNullPhaseName() throws Exception {
|
||||
Sun sun = this.sun;
|
||||
handler.publishDailyInfo();
|
||||
Sun sun = handler.sun;
|
||||
assertNotNull(sun);
|
||||
sun.getPhase().setName(null);
|
||||
|
||||
assertEquals(UnDefType.UNDEF, PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"),
|
||||
Objects.requireNonNull(config), sun, TIME_ZONE));
|
||||
when(channel.getUID()).thenReturn(new ChannelUID("astro:sun:home:phase#name"));
|
||||
assertEquals(UnDefType.UNDEF, handler.getState(channel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetStateWhenNotNullPhaseName() throws Exception {
|
||||
Sun sun = this.sun;
|
||||
assertNotNull(sun);
|
||||
sun.getPhase().setName(SunPhaseName.DAYLIGHT);
|
||||
|
||||
assertEquals(new StringType("DAYLIGHT"), PropertyUtils.getState(new ChannelUID("astro:sun:home:phase#name"),
|
||||
Objects.requireNonNull(config), sun, TIME_ZONE));
|
||||
handler.publishPositionalInfo();
|
||||
when(channel.getUID()).thenReturn(new ChannelUID("astro:sun:home:phase#name"));
|
||||
assertEquals(new StringType("NIGHT"), handler.getState(channel));
|
||||
}
|
||||
|
||||
@Test
|
||||
+7
-6
@@ -10,17 +10,17 @@
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.handler.test;
|
||||
package org.openhab.binding.astro.internal.handler;
|
||||
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.THING_TYPE_SUN;
|
||||
import static org.openhab.binding.astro.test.cases.AstroBindingTestsData.*;
|
||||
import static org.openhab.binding.astro.internal.CommonTestConstants.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.time.ZoneId;
|
||||
|
||||
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;
|
||||
@@ -42,7 +42,7 @@ import org.openhab.core.thing.binding.ThingHandlerCallback;
|
||||
* @author Svilen Valkanov - Reworked to plain unit tests, removed irrelevant tests
|
||||
* @author Christoph Weitkamp - Migrated tests to pure Java
|
||||
*/
|
||||
public class AstroValidConfigurationTest {
|
||||
public class ValidConfigurationTest {
|
||||
|
||||
private static final String NULL_LONGITUDE = "51.2,null";
|
||||
private static final String NULL_LATITUDE = "null,25.4";
|
||||
@@ -150,7 +150,8 @@ public class AstroValidConfigurationTest {
|
||||
TimeZoneProvider timeZoneProvider = mock(TimeZoneProvider.class);
|
||||
LocaleProvider localeProvider = mock(LocaleProvider.class);
|
||||
when(timeZoneProvider.getTimeZone()).thenReturn(ZoneId.systemDefault());
|
||||
ThingHandler sunHandler = new SunHandler(thing, cronScheduler, timeZoneProvider, localeProvider);
|
||||
ThingHandler sunHandler = new SunHandler(thing, cronScheduler, timeZoneProvider, localeProvider,
|
||||
InstantSource.fixed(Instant.ofEpochMilli(1645671600000L)));
|
||||
sunHandler.setCallback(callback);
|
||||
|
||||
sunHandler.initialize();
|
||||
+37
-26
@@ -14,6 +14,8 @@ package org.openhab.binding.astro.internal.job;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.TimeZone;
|
||||
@@ -35,6 +37,7 @@ import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
public class JobTest {
|
||||
|
||||
private static final TimeZone TIME_ZONE = TimeZone.getTimeZone("Asia/Tbilisi");
|
||||
private static final InstantSource INSTANT_SOURCE = InstantSource.fixed(Instant.ofEpochMilli(1645671600000L));
|
||||
|
||||
@BeforeEach
|
||||
public void init() {
|
||||
@@ -47,21 +50,23 @@ public class JobTest {
|
||||
config.earliest = "08:00";
|
||||
config.latest = "22:00";
|
||||
config.forceEvent = true;
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0, TIME_ZONE, Locale.ROOT);
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
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, TIME_ZONE, Locale.ROOT),
|
||||
DateTimeUtils.createCalendarForToday(23, 10, TIME_ZONE, Locale.ROOT));
|
||||
Range bothNNShouldCorrect = new Range(
|
||||
DateTimeUtils.createCalendarForToday(6, 0, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE),
|
||||
DateTimeUtils.createCalendarForToday(23, 10, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE));
|
||||
Range bothNNShouldNotCorrect = new Range(pointInTime, pointInTime);
|
||||
|
||||
// act
|
||||
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 startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
Range endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
Range bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
Range bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT,
|
||||
INSTANT_SOURCE);
|
||||
Range bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE,
|
||||
Locale.ROOT);
|
||||
Locale.ROOT, INSTANT_SOURCE);
|
||||
|
||||
Calendar fixedStart = DateTimeUtils.getAdjustedEarliest(pointInTime, config);
|
||||
Calendar fixedEnd = DateTimeUtils.getAdjustedLatest(pointInTime, config);
|
||||
@@ -90,11 +95,13 @@ public class JobTest {
|
||||
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);
|
||||
startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT,
|
||||
INSTANT_SOURCE);
|
||||
bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE, Locale.ROOT,
|
||||
INSTANT_SOURCE);
|
||||
|
||||
// assert again
|
||||
startNullResultStart = startNullResult.getStart();
|
||||
@@ -121,11 +128,13 @@ public class JobTest {
|
||||
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);
|
||||
startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT,
|
||||
INSTANT_SOURCE);
|
||||
bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE, Locale.ROOT,
|
||||
INSTANT_SOURCE);
|
||||
|
||||
// assert yet again
|
||||
startNullResultStart = startNullResult.getStart();
|
||||
@@ -151,21 +160,23 @@ public class JobTest {
|
||||
config.earliest = "08:00";
|
||||
config.latest = "22:00";
|
||||
config.forceEvent = false;
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0, TIME_ZONE, Locale.ROOT);
|
||||
Calendar pointInTime = DateTimeUtils.createCalendarForToday(12, 0, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
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, TIME_ZONE, Locale.ROOT),
|
||||
DateTimeUtils.createCalendarForToday(23, 10, TIME_ZONE, Locale.ROOT));
|
||||
Range bothNNShouldCorrect = new Range(
|
||||
DateTimeUtils.createCalendarForToday(6, 0, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE),
|
||||
DateTimeUtils.createCalendarForToday(23, 10, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE));
|
||||
Range bothNNShouldNotCorrect = new Range(pointInTime, pointInTime);
|
||||
|
||||
// act
|
||||
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 startNullResult = Job.adjustRangeToConfig(startNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
Range endNullResult = Job.adjustRangeToConfig(endNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
Range bothNullResult = Job.adjustRangeToConfig(bothNull, config, TIME_ZONE, Locale.ROOT, INSTANT_SOURCE);
|
||||
Range bothNNShouldCorrectResult = Job.adjustRangeToConfig(bothNNShouldCorrect, config, TIME_ZONE, Locale.ROOT,
|
||||
INSTANT_SOURCE);
|
||||
Range bothNNSouldNotCorrectResult = Job.adjustRangeToConfig(bothNNShouldNotCorrect, config, TIME_ZONE,
|
||||
Locale.ROOT);
|
||||
Locale.ROOT, INSTANT_SOURCE);
|
||||
|
||||
Calendar fixedStart = DateTimeUtils.getAdjustedEarliest(pointInTime, config);
|
||||
Calendar fixdedEnd = DateTimeUtils.getAdjustedLatest(pointInTime, config);
|
||||
|
||||
+5
-3
@@ -15,6 +15,7 @@ package org.openhab.binding.astro.internal.util;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.InstantSource;
|
||||
import java.util.Calendar;
|
||||
import java.util.GregorianCalendar;
|
||||
import java.util.Locale;
|
||||
@@ -65,17 +66,18 @@ public class DateTimeUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testCreateCalendarForToday() {
|
||||
Calendar cal = DateTimeUtils.createCalendarForToday(8, 0, TIME_ZONE, Locale.ROOT);
|
||||
InstantSource is = InstantSource.fixed(Instant.ofEpochMilli(1645671600000L));
|
||||
Calendar cal = DateTimeUtils.createCalendarForToday(8, 0, TIME_ZONE, Locale.ROOT, is);
|
||||
assertEquals(8, cal.get(Calendar.HOUR_OF_DAY));
|
||||
assertEquals(0, cal.get(Calendar.MINUTE));
|
||||
assertEquals(0, cal.get(Calendar.SECOND));
|
||||
assertEquals(0, cal.get(Calendar.MILLISECOND));
|
||||
cal = DateTimeUtils.createCalendarForToday(22, 59, TIME_ZONE, Locale.ROOT);
|
||||
cal = DateTimeUtils.createCalendarForToday(22, 59, TIME_ZONE, Locale.ROOT, is);
|
||||
assertEquals(22, cal.get(Calendar.HOUR_OF_DAY));
|
||||
assertEquals(59, cal.get(Calendar.MINUTE));
|
||||
assertEquals(0, cal.get(Calendar.SECOND));
|
||||
assertEquals(0, cal.get(Calendar.MILLISECOND));
|
||||
cal = DateTimeUtils.createCalendarForToday(0, 0, TIME_ZONE, Locale.ROOT);
|
||||
cal = DateTimeUtils.createCalendarForToday(0, 0, TIME_ZONE, Locale.ROOT, is);
|
||||
assertEquals(0, cal.get(Calendar.HOUR_OF_DAY));
|
||||
assertEquals(0, cal.get(Calendar.MINUTE));
|
||||
assertEquals(0, cal.get(Calendar.SECOND));
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
This content is produced and maintained by the openHAB project.
|
||||
|
||||
* Project home: https://www.openhab.org
|
||||
|
||||
== Declared Project Licenses
|
||||
|
||||
This program and the accompanying materials are made available under the terms
|
||||
of the Eclipse Public License 2.0 which is available at
|
||||
https://www.eclipse.org/legal/epl-2.0/.
|
||||
|
||||
== Source Code
|
||||
|
||||
https://github.com/openhab/openhab-addons
|
||||
@@ -1,77 +0,0 @@
|
||||
-include: ../itest-common.bndrun
|
||||
|
||||
Bundle-SymbolicName: ${project.artifactId}
|
||||
Fragment-Host: org.openhab.binding.astro
|
||||
|
||||
-runrequires: bnd.identity;id='org.openhab.binding.astro.tests'
|
||||
|
||||
#
|
||||
# done
|
||||
#
|
||||
-runbundles: \
|
||||
jakarta.xml.bind-api;version='[2.3.3,2.3.4)',\
|
||||
org.apache.servicemix.specs.activation-api-1.2.1;version='[1.2.1,1.2.2)',\
|
||||
org.glassfish.hk2.osgi-resource-locator;version='[3.0.0,3.0.1)',\
|
||||
jakarta.inject.jakarta.inject-api;version='[2.0.1,2.0.2)',\
|
||||
si-units;version='[2.2.3,2.2.4)',\
|
||||
si-quantity;version='[2.2.3,2.2.4)',\
|
||||
org.osgi.util.function;version='[1.2.0,1.2.1)',\
|
||||
org.apache.felix.configadmin;version='[1.9.26,1.9.27)',\
|
||||
org.osgi.service.component;version='[1.5.1,1.5.2)',\
|
||||
net.bytebuddy.byte-buddy;version='[1.17.6,1.17.7)',\
|
||||
net.bytebuddy.byte-buddy-agent;version='[1.17.6,1.17.7)',\
|
||||
org.mockito.mockito-core;version='[5.19.0,5.19.1)',\
|
||||
org.objenesis;version='[3.3.0,3.3.1)',\
|
||||
xstream;version='[1.4.21,1.4.22)',\
|
||||
javax.measure.unit-api;version='[2.2.0,2.2.1)',\
|
||||
tech.units.indriya;version='[2.2.3,2.2.4)',\
|
||||
uom-lib-common;version='[2.2.0,2.2.1)',\
|
||||
io.methvin.directory-watcher;version='[0.19.1,0.19.2)',\
|
||||
com.sun.xml.bind.jaxb-osgi;version='[2.3.9,2.3.10)',\
|
||||
org.apache.felix.scr;version='[2.2.6,2.2.7)',\
|
||||
org.eclipse.equinox.event;version='[1.6.300,1.6.301)',\
|
||||
org.osgi.service.event;version='[1.4.1,1.4.2)',\
|
||||
org.osgi.util.promise;version='[1.3.0,1.3.1)',\
|
||||
com.google.gson;version='[2.13.2,2.13.3)',\
|
||||
junit-jupiter-api;version='[5.13.4,5.13.5)',\
|
||||
junit-jupiter-engine;version='[5.13.4,5.13.5)',\
|
||||
junit-jupiter-params;version='[5.13.4,5.13.5)',\
|
||||
junit-platform-commons;version='[1.13.4,1.13.5)',\
|
||||
junit-platform-engine;version='[1.13.4,1.13.5)',\
|
||||
junit-platform-launcher;version='[1.13.4,1.13.5)',\
|
||||
org.opentest4j;version='[1.3.0,1.3.1)',\
|
||||
org.osgi.service.component.annotations;version='[1.5.1,1.5.2)',\
|
||||
com.sun.jna;version='[5.18.1,5.18.2)',\
|
||||
org.ops4j.pax.logging.pax-logging-api;version='[2.3.0,2.3.1)',\
|
||||
org.openhab.binding.astro;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.binding.astro.tests;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.addon;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.config.core;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.config.discovery;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.io.console;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.semantics;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.thing;version='[5.2.0,5.2.1)',\
|
||||
org.openhab.core.transform;version='[5.2.0,5.2.1)',\
|
||||
biz.aQute.tester.junit-platform;version='[7.1.0,7.1.1)',\
|
||||
ch.qos.logback.classic;version='[1.5.24,1.5.25)',\
|
||||
ch.qos.logback.core;version='[1.5.24,1.5.25)',\
|
||||
org.apache.aries.spifly.dynamic.bundle;version='[1.3.7,1.3.8)',\
|
||||
org.apache.felix.http.servlet-api;version='[1.2.0,1.2.1)',\
|
||||
org.eclipse.jetty.http;version='[9.4.57,9.4.58)',\
|
||||
org.eclipse.jetty.io;version='[9.4.57,9.4.58)',\
|
||||
org.eclipse.jetty.security;version='[9.4.57,9.4.58)',\
|
||||
org.eclipse.jetty.server;version='[9.4.57,9.4.58)',\
|
||||
org.eclipse.jetty.servlet;version='[9.4.57,9.4.58)',\
|
||||
org.eclipse.jetty.util;version='[9.4.57,9.4.58)',\
|
||||
org.eclipse.jetty.util.ajax;version='[9.4.57,9.4.58)',\
|
||||
org.hamcrest;version='[3.0.0,3.0.1)',\
|
||||
org.objectweb.asm;version='[9.9.0,9.9.1)',\
|
||||
org.objectweb.asm.commons;version='[9.6.0,9.6.1)',\
|
||||
org.objectweb.asm.tree;version='[9.6.0,9.6.1)',\
|
||||
org.objectweb.asm.tree.analysis;version='[9.6.0,9.6.1)',\
|
||||
org.objectweb.asm.util;version='[9.6.0,9.6.1)',\
|
||||
org.openhab.core.test;version='[5.2.0,5.2.1)',\
|
||||
org.osgi.service.cm;version='[1.6.1,1.6.2)',\
|
||||
jakarta.annotation-api;version='[2.1.1,2.1.2)'
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.openhab.addons.itests</groupId>
|
||||
<artifactId>org.openhab.addons.reactor.itests</artifactId>
|
||||
<version>5.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>org.openhab.binding.astro.tests</artifactId>
|
||||
|
||||
<name>openHAB Add-ons :: Integration Tests :: Astro Binding Tests</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.openhab.addons.bundles</groupId>
|
||||
<artifactId>org.openhab.binding.astro</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010-2026 Contributors to the openHAB project
|
||||
*
|
||||
* See the NOTICE file(s) distributed with this work for additional
|
||||
* information.
|
||||
*
|
||||
* This program and the accompanying materials are made available under the
|
||||
* terms of the Eclipse Public License 2.0 which is available at
|
||||
* http://www.eclipse.org/legal/epl-2.0
|
||||
*
|
||||
* SPDX-License-Identifier: EPL-2.0
|
||||
*/
|
||||
package org.openhab.binding.astro.test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
|
||||
import static org.openhab.binding.astro.test.cases.AstroBindingTestsData.*;
|
||||
import static org.openhab.binding.astro.test.cases.AstroParametrizedTestCases.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
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;
|
||||
import org.openhab.binding.astro.internal.calc.MoonCalc;
|
||||
import org.openhab.binding.astro.internal.calc.SunCalc;
|
||||
import org.openhab.binding.astro.internal.config.AstroChannelConfig;
|
||||
import org.openhab.binding.astro.internal.model.Planet;
|
||||
import org.openhab.binding.astro.internal.util.PropertyUtils;
|
||||
import org.openhab.binding.astro.test.cases.AstroParametrizedTestCases;
|
||||
import org.openhab.core.thing.ChannelUID;
|
||||
import org.openhab.core.thing.ThingUID;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* Tests for the Astro Channels state
|
||||
*
|
||||
* @see AstroParametrizedTestCases
|
||||
* @author Petar Valchev - Initial contribution
|
||||
* @author Svilen Valkanov - Reworked to plain unit tests
|
||||
* @author Erdoan Hadzhiyusein - Adapted the class to work with the new DateTimeType
|
||||
* @author Christoph Weitkamp - Migrated tests to pure Java
|
||||
*/
|
||||
public class AstroStateTest {
|
||||
|
||||
// These test result timestamps are adapted for the +03:00 time zone
|
||||
private static final ZoneId ZONE_ID = ZoneId.of("+03:00");
|
||||
|
||||
public static List<Object[]> data() {
|
||||
AstroParametrizedTestCases cases = new AstroParametrizedTestCases();
|
||||
return cases.getCases();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("data")
|
||||
public void testParametrized(String thingID, String channelId, State expectedState) {
|
||||
try {
|
||||
assertStateUpdate(thingID, channelId, expectedState);
|
||||
} catch (Exception e) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
TimeZone.getTimeZone(ZONE_ID));
|
||||
assertEquals(expectedState, state);
|
||||
}
|
||||
|
||||
private ThingUID getThingUID(String thingID) {
|
||||
switch (thingID) {
|
||||
case (TEST_SUN_THING_ID):
|
||||
return new ThingUID(THING_TYPE_SUN, thingID);
|
||||
case (TEST_MOON_THING_ID):
|
||||
return new ThingUID(THING_TYPE_MOON, thingID);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private Planet getPlanet(String thingID) {
|
||||
LocalDateTime time = LocalDateTime.of(TEST_YEAR, TEST_MONTH, TEST_DAY, 0, 0);
|
||||
ZonedDateTime zonedTime = ZonedDateTime.ofLocal(time, ZONE_ID, null);
|
||||
Calendar calendar = GregorianCalendar.from(zonedTime);
|
||||
switch (thingID) {
|
||||
case (TEST_SUN_THING_ID):
|
||||
SunCalc sunCalc = new SunCalc();
|
||||
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, TimeZone.getTimeZone(ZONE_ID),
|
||||
Locale.getDefault());
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@
|
||||
<modules>
|
||||
<module>org.openhab.automation.groovyscripting.tests</module>
|
||||
<module>org.openhab.automation.jsscriptingnashorn.tests</module>
|
||||
<module>org.openhab.binding.astro.tests</module>
|
||||
<module>org.openhab.binding.avmfritz.tests</module>
|
||||
<module>org.openhab.binding.feed.tests</module>
|
||||
<module>org.openhab.binding.homeassistant.tests</module>
|
||||
|
||||
Reference in New Issue
Block a user