[astro] Fix returning wrong sun phase name (#14078)
* Add tests and fix very minor bug * Correct wrong test * Update tests and fix sorting * Some checkstyle improvements Signed-off-by: lsiepel <leosiepel@gmail.com>
This commit is contained in:
parent
7de25352ef
commit
71ef3d9f4e
|
@ -12,7 +12,13 @@
|
||||||
*/
|
*/
|
||||||
package org.openhab.binding.astro.internal.calc;
|
package org.openhab.binding.astro.internal.calc;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import org.openhab.binding.astro.internal.model.Eclipse;
|
import org.openhab.binding.astro.internal.model.Eclipse;
|
||||||
|
@ -251,9 +257,9 @@ public class SunCalc {
|
||||||
sun.setSeason(seasonCalc.getSeason(calendar, latitude, useMeteorologicalSeason));
|
sun.setSeason(seasonCalc.getSeason(calendar, latitude, useMeteorologicalSeason));
|
||||||
|
|
||||||
// phase
|
// phase
|
||||||
for (Entry<SunPhaseName, Range> rangeEntry : sun.getAllRanges().entrySet()) {
|
for (Entry<SunPhaseName, Range> rangeEntry : sortByValue(sun.getAllRanges()).entrySet()) {
|
||||||
SunPhaseName entryPhase = rangeEntry.getKey();
|
SunPhaseName entryPhase = rangeEntry.getKey();
|
||||||
if (rangeEntry.getValue().matches(Calendar.getInstance())) {
|
if (rangeEntry.getValue().matches(calendar)) {
|
||||||
if (entryPhase == SunPhaseName.MORNING_NIGHT || entryPhase == SunPhaseName.EVENING_NIGHT) {
|
if (entryPhase == SunPhaseName.MORNING_NIGHT || entryPhase == SunPhaseName.EVENING_NIGHT) {
|
||||||
sun.getPhase().setName(SunPhaseName.NIGHT);
|
sun.getPhase().setName(SunPhaseName.NIGHT);
|
||||||
} else {
|
} else {
|
||||||
|
@ -336,4 +342,24 @@ public class SunCalc {
|
||||||
private double getSunriseJulianDate(double jtransit, double jset) {
|
private double getSunriseJulianDate(double jtransit, double jset) {
|
||||||
return jtransit - (jset - jtransit);
|
return jtransit - (jset - jtransit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Map<SunPhaseName, Range> sortByValue(Map<SunPhaseName, Range> map) {
|
||||||
|
List<Entry<SunPhaseName, Range>> list = new ArrayList<>(map.entrySet());
|
||||||
|
|
||||||
|
Collections.sort(list, new Comparator<Entry<SunPhaseName, Range>>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Entry<SunPhaseName, Range> p1, Entry<SunPhaseName, Range> p2) {
|
||||||
|
Range p1Range = p1.getValue();
|
||||||
|
Range p2Range = p2.getValue();
|
||||||
|
return p1Range.compareTo(p2Range);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Map<SunPhaseName, Range> result = new LinkedHashMap<>();
|
||||||
|
for (Entry<SunPhaseName, Range> entry : list) {
|
||||||
|
result.put(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,7 +37,6 @@ public class SunZodiacCalc {
|
||||||
* Returns the zodiac for the specified calendar.
|
* Returns the zodiac for the specified calendar.
|
||||||
*/
|
*/
|
||||||
public Optional<SunZodiac> getZodiac(Calendar calendar) {
|
public Optional<SunZodiac> getZodiac(Calendar calendar) {
|
||||||
|
|
||||||
int year = calendar.get(Calendar.YEAR);
|
int year = calendar.get(Calendar.YEAR);
|
||||||
List<SunZodiac> zodiacs;
|
List<SunZodiac> zodiacs;
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,6 @@ public interface Job extends SchedulerRunnable, Runnable {
|
||||||
*/
|
*/
|
||||||
public static void scheduleEvent(String thingUID, AstroThingHandler astroHandler, Calendar eventAt,
|
public static void scheduleEvent(String thingUID, AstroThingHandler astroHandler, Calendar eventAt,
|
||||||
List<String> events, String channelId, boolean configAlreadyApplied) {
|
List<String> events, String channelId, boolean configAlreadyApplied) {
|
||||||
|
|
||||||
if (events.isEmpty()) {
|
if (events.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ public class MoonPhase {
|
||||||
private Calendar firstQuarter;
|
private Calendar firstQuarter;
|
||||||
private Calendar full;
|
private Calendar full;
|
||||||
private Calendar thirdQuarter;
|
private Calendar thirdQuarter;
|
||||||
private Calendar _new;
|
private Calendar newCalendar;
|
||||||
private double age;
|
private double age;
|
||||||
private double illumination;
|
private double illumination;
|
||||||
private double agePercent;
|
private double agePercent;
|
||||||
|
@ -85,14 +85,14 @@ public class MoonPhase {
|
||||||
* Returns the date of the new moon.
|
* Returns the date of the new moon.
|
||||||
*/
|
*/
|
||||||
public Calendar getNew() {
|
public Calendar getNew() {
|
||||||
return _new;
|
return newCalendar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the date of the new moon.
|
* Sets the date of the new moon.
|
||||||
*/
|
*/
|
||||||
public void setNew(Calendar _new) {
|
public void setNew(Calendar newCalendar) {
|
||||||
this._new = _new;
|
this.newCalendar = newCalendar;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,6 +15,7 @@ package org.openhab.binding.astro.internal.model;
|
||||||
import static org.openhab.core.library.unit.MetricPrefix.MILLI;
|
import static org.openhab.core.library.unit.MetricPrefix.MILLI;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
|
import java.util.Comparator;
|
||||||
|
|
||||||
import javax.measure.quantity.Time;
|
import javax.measure.quantity.Time;
|
||||||
|
|
||||||
|
@ -81,4 +82,13 @@ public class Range {
|
||||||
long matchEnd = end != null ? end.getTimeInMillis() : DateTimeUtils.endOfDayDate(cal).getTimeInMillis();
|
long matchEnd = end != null ? end.getTimeInMillis() : DateTimeUtils.endOfDayDate(cal).getTimeInMillis();
|
||||||
return cal.getTimeInMillis() >= matchStart && cal.getTimeInMillis() < matchEnd;
|
return cal.getTimeInMillis() >= matchStart && cal.getTimeInMillis() < matchEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Comparator<Calendar> nullSafeCalendarComparator = Comparator.nullsFirst(Calendar::compareTo);
|
||||||
|
|
||||||
|
private static Comparator<Range> rangeComparator = Comparator.comparing(Range::getStart, nullSafeCalendarComparator)
|
||||||
|
.thenComparing(Range::getEnd, nullSafeCalendarComparator);
|
||||||
|
|
||||||
|
public int compareTo(Range that) {
|
||||||
|
return rangeComparator.compare(this, that);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,8 +80,8 @@ public class SunCalcTest {
|
||||||
assertNotNull(sun.getMorningNight());
|
assertNotNull(sun.getMorningNight());
|
||||||
assertNotNull(sun.getEveningNight());
|
assertNotNull(sun.getEveningNight());
|
||||||
|
|
||||||
// for an old date the phase is always null
|
// for an old date the phase should also be calculated
|
||||||
assertNull(sun.getPhase().getName());
|
assertNotNull(sun.getPhase().getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -274,6 +274,34 @@ public class SunCalcTest {
|
||||||
sun.getAllRanges().get(SunPhaseName.EVENING_NIGHT).getStart());
|
sun.getAllRanges().get(SunPhaseName.EVENING_NIGHT).getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIssue7642CivilDawnEnd() {
|
||||||
|
TimeZone tZone = TimeZone.getTimeZone("Europe/London");
|
||||||
|
Calendar tDate = SunCalcTest.newCalendar(2020, Calendar.MAY, 13, 5, 12, tZone);
|
||||||
|
|
||||||
|
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true);
|
||||||
|
assertEquals(SunPhaseName.CIVIL_DAWN, sun.getPhase().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIssue7642SunRiseStart() {
|
||||||
|
// SunCalc.ranges was not sorted, causing unexpected output in corner cases.
|
||||||
|
TimeZone tZone = TimeZone.getTimeZone("Europe/London");
|
||||||
|
Calendar tDate = SunCalcTest.newCalendar(2020, Calendar.MAY, 13, 5, 13, tZone);
|
||||||
|
|
||||||
|
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true);
|
||||||
|
assertEquals(SunPhaseName.SUN_RISE, sun.getPhase().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testIssue7642DaylightStart() {
|
||||||
|
TimeZone tZone = TimeZone.getTimeZone("Europe/London");
|
||||||
|
Calendar tDate = SunCalcTest.newCalendar(2020, Calendar.MAY, 13, 5, 18, tZone);
|
||||||
|
|
||||||
|
Sun sun = sunCalc.getSunInfo(tDate, 53.524695, -2.4, 0.0, true);
|
||||||
|
assertEquals(SunPhaseName.DAYLIGHT, sun.getPhase().getName());
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Constructs a <code>GregorianCalendar</code> with the given date and time set
|
* Constructs a <code>GregorianCalendar</code> with the given date and time set
|
||||||
* for the provided time zone.
|
* for the provided time zone.
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class SunTest {
|
||||||
private Sun sun;
|
private Sun sun;
|
||||||
private AstroChannelConfig config;
|
private AstroChannelConfig config;
|
||||||
|
|
||||||
private static ZoneId ZONE = ZoneId.systemDefault();
|
private static final ZoneId ZONE = ZoneId.systemDefault();
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
public void init() {
|
public void init() {
|
||||||
|
|
Loading…
Reference in New Issue