mirror of
https://github.com/danieldemus/openhab-addons
synced 2026-07-29 12:34:21 +02:00
[astro] Tweak sun and moon position classes (#20063)
* Revamp sun and moon position Signed-off-by: gael@lhopital.org <gael@lhopital.org>
This commit is contained in:
+17
-6
@@ -33,6 +33,7 @@ import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.thing.binding.ThingActions;
|
||||
import org.openhab.core.thing.binding.ThingActionsScope;
|
||||
import org.openhab.core.thing.binding.ThingHandler;
|
||||
import org.openhab.core.types.State;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
@@ -77,9 +78,14 @@ public class AstroActions implements ThingActions {
|
||||
public @Nullable @ActionOutput(name = "result", label = "Azimuth", type = "org.openhab.core.library.types.QuantityType<javax.measure.quantity.Angle>") QuantityType<Angle> getAzimuth(
|
||||
@ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date) {
|
||||
logger.debug("Astro action 'getAzimuth' called");
|
||||
AstroThingHandler theHandler = this.handler;
|
||||
if (theHandler != null) {
|
||||
return theHandler.getAzimuth(date != null ? date : ZonedDateTime.now(timeZoneProvider.getTimeZone()));
|
||||
if (handler instanceof AstroThingHandler local) {
|
||||
State result = local.getAzimuth(date != null ? date : ZonedDateTime.now(timeZoneProvider.getTimeZone()));
|
||||
if (result instanceof QuantityType<?>) {
|
||||
@SuppressWarnings("unchecked")
|
||||
QuantityType<Angle> qta = (QuantityType<Angle>) result;
|
||||
return qta;
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
logger.info("Astro Action service ThingHandler is null!");
|
||||
}
|
||||
@@ -90,9 +96,14 @@ public class AstroActions implements ThingActions {
|
||||
public @Nullable @ActionOutput(name = "result", label = "Elevation", type = "org.openhab.core.library.types.QuantityType<javax.measure.quantity.Angle>") QuantityType<Angle> getElevation(
|
||||
@ActionInput(name = "date", label = "Date", required = false, description = "Considered date") @Nullable ZonedDateTime date) {
|
||||
logger.debug("Astro action 'getElevation' called");
|
||||
AstroThingHandler theHandler = this.handler;
|
||||
if (theHandler != null) {
|
||||
return theHandler.getElevation(date != null ? date : ZonedDateTime.now(timeZoneProvider.getTimeZone()));
|
||||
if (handler instanceof AstroThingHandler local) {
|
||||
State result = local.getElevation(date != null ? date : ZonedDateTime.now(timeZoneProvider.getTimeZone()));
|
||||
if (result instanceof QuantityType<?>) {
|
||||
@SuppressWarnings("unchecked")
|
||||
QuantityType<Angle> qta = (QuantityType<Angle>) result;
|
||||
return qta;
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
logger.info("Astro Action service ThingHandler is null!");
|
||||
}
|
||||
|
||||
+4
-5
@@ -29,6 +29,7 @@ import org.openhab.binding.astro.internal.model.EclipseType;
|
||||
import org.openhab.binding.astro.internal.model.Moon;
|
||||
import org.openhab.binding.astro.internal.model.MoonPhase;
|
||||
import org.openhab.binding.astro.internal.model.MoonPhaseName;
|
||||
import org.openhab.binding.astro.internal.model.MoonPosition;
|
||||
import org.openhab.binding.astro.internal.model.Position;
|
||||
import org.openhab.binding.astro.internal.model.Range;
|
||||
import org.openhab.binding.astro.internal.util.DateTimeUtils;
|
||||
@@ -92,7 +93,7 @@ public class MoonCalc {
|
||||
double jdate = getEclipse(calendar, EclipseType.MOON, julianDateMidnight, eclipseKind);
|
||||
Calendar eclipseDate = DateTimeUtils.toCalendar(jdate, zone, locale);
|
||||
if (eclipseDate != null) {
|
||||
eclipse.set(eclipseKind, eclipseDate, new Position());
|
||||
eclipse.set(eclipseKind, eclipseDate, Position.NULL);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -600,10 +601,8 @@ public class MoonCalc {
|
||||
double[] raDecTopo = geoEqu2TopoEqu(raDec, distance, lat, lmst);
|
||||
double[] azAlt = equ2AzAlt(raDecTopo[0], raDecTopo[1], lat, lmst);
|
||||
|
||||
Position position = moon.getPosition();
|
||||
position.setAzimuth(Math.toDegrees(azAlt[0]));
|
||||
position.setElevation(Math.toDegrees(azAlt[1]) + refraction(azAlt[1]));
|
||||
|
||||
moon.setPosition(
|
||||
new MoonPosition(Math.toDegrees(azAlt[0]), Math.toDegrees(azAlt[1]) + refraction(azAlt[1]), moonLon));
|
||||
moon.setZodiac(ZodiacCalc.calculate(moonLon, null));
|
||||
}
|
||||
|
||||
|
||||
+2
-10
@@ -83,12 +83,8 @@ public class SunCalc {
|
||||
|
||||
double azimuth = Math.toDegrees(getAzimuth(th, a, phi, d));
|
||||
double elevation = Math.toDegrees(getElevation(th, a, phi, d));
|
||||
double shadeLength = getShadeLength(elevation);
|
||||
|
||||
Position position = sun.getPosition();
|
||||
position.setAzimuth(azimuth + 180);
|
||||
position.setElevation(elevation);
|
||||
position.setShadeLength(shadeLength);
|
||||
sun.setPosition(new Position(azimuth + 180, elevation));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -232,7 +228,7 @@ public class SunCalc {
|
||||
double jdate = mc.getEclipse(calendar, EclipseType.SUN, j, eclipseKind);
|
||||
Calendar eclipseDate = DateTimeUtils.toCalendar(jdate, zone, locale);
|
||||
if (eclipseDate != null) {
|
||||
eclipse.set(eclipseKind, eclipseDate, new Position());
|
||||
eclipse.set(eclipseKind, eclipseDate, Position.NULL);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -315,10 +311,6 @@ public class SunCalc {
|
||||
return Math.asin(Math.sin(phi) * Math.sin(d) + Math.cos(phi) * Math.cos(d) * Math.cos(th - a));
|
||||
}
|
||||
|
||||
private double getShadeLength(double elevation) {
|
||||
return 1 / MathUtils.tanDeg(elevation);
|
||||
}
|
||||
|
||||
private double getHourAngle(double h, double phi, double d) {
|
||||
return Math.acos((Math.sin(h) - Math.sin(phi) * Math.sin(d)) / (Math.cos(phi) * Math.cos(d)));
|
||||
}
|
||||
|
||||
+6
-7
@@ -35,8 +35,6 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import javax.measure.quantity.Angle;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.astro.internal.action.AstroActions;
|
||||
@@ -49,7 +47,6 @@ import org.openhab.binding.astro.internal.model.Position;
|
||||
import org.openhab.binding.astro.internal.util.PropertyUtils;
|
||||
import org.openhab.core.i18n.LocaleProvider;
|
||||
import org.openhab.core.i18n.TimeZoneProvider;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.scheduler.CronScheduler;
|
||||
import org.openhab.core.scheduler.ScheduledCompletableFuture;
|
||||
import org.openhab.core.thing.Channel;
|
||||
@@ -59,6 +56,8 @@ import org.openhab.core.thing.ThingStatusDetail;
|
||||
import org.openhab.core.thing.binding.BaseThingHandler;
|
||||
import org.openhab.core.thing.binding.ThingHandlerService;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -402,14 +401,14 @@ public abstract class AstroThingHandler extends BaseThingHandler {
|
||||
|
||||
public abstract @Nullable Position getPositionAt(ZonedDateTime date);
|
||||
|
||||
public @Nullable QuantityType<Angle> getAzimuth(ZonedDateTime date) {
|
||||
public State getAzimuth(ZonedDateTime date) {
|
||||
Position position = getPositionAt(date);
|
||||
return position != null ? position.getAzimuth() : null;
|
||||
return position != null ? position.getAzimuth() : UnDefType.NULL;
|
||||
}
|
||||
|
||||
public @Nullable QuantityType<Angle> getElevation(ZonedDateTime date) {
|
||||
public State getElevation(ZonedDateTime date) {
|
||||
Position position = getPositionAt(date);
|
||||
return position != null ? position.getElevation() : null;
|
||||
return position != null ? position.getElevation() : UnDefType.NULL;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ public class Moon extends RiseSet implements Planet {
|
||||
|
||||
private MoonPhase phase = new MoonPhase();
|
||||
private Eclipse eclipse = new Eclipse(EclipseKind.PARTIAL, EclipseKind.TOTAL);
|
||||
private Position position = new Position();
|
||||
private Position position = MoonPosition.NULL;
|
||||
private Zodiac zodiac = Zodiac.NULL;
|
||||
|
||||
public Moon() {
|
||||
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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.model;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
|
||||
/**
|
||||
* Immutable class holding Moon Position information
|
||||
*
|
||||
* @author Gaël L'hopital - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class MoonPosition extends Position {
|
||||
public static final Position NULL = new MoonPosition();
|
||||
private final double longitude;
|
||||
|
||||
private MoonPosition() {
|
||||
super(Double.NaN, Double.NaN);
|
||||
this.longitude = Double.NaN;
|
||||
}
|
||||
|
||||
public MoonPosition(double azimuth, double elevation, double longitude) {
|
||||
super(azimuth, elevation);
|
||||
this.longitude = longitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the moon longitude
|
||||
*/
|
||||
public double getLongitude() {
|
||||
return longitude;
|
||||
}
|
||||
}
|
||||
+21
-36
@@ -12,14 +12,16 @@
|
||||
*/
|
||||
package org.openhab.binding.astro.internal.model;
|
||||
|
||||
import javax.measure.quantity.Angle;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.binding.astro.internal.util.MathUtils;
|
||||
import org.openhab.core.library.types.DecimalType;
|
||||
import org.openhab.core.library.types.QuantityType;
|
||||
import org.openhab.core.library.unit.Units;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
* Holds the calculated azimuth and elevation.
|
||||
* Immutable class holding calculated azimuth and elevation.
|
||||
*
|
||||
* @author Gerhard Riegler - Initial contribution
|
||||
* @author Gaël L'hopital - Added shade length
|
||||
@@ -27,39 +29,35 @@ import org.openhab.core.library.unit.Units;
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class Position {
|
||||
public static final Position NULL = new Position();
|
||||
private final double azimuth;
|
||||
private final double elevation;
|
||||
|
||||
private double azimuth;
|
||||
private double elevation;
|
||||
private double shadeLength;
|
||||
|
||||
public Position() {
|
||||
private Position() {
|
||||
this(Double.NaN, Double.NaN);
|
||||
}
|
||||
|
||||
public Position(double azimuth, double elevation, double shadeLength) {
|
||||
public Position(double azimuth, double elevation) {
|
||||
this.azimuth = azimuth;
|
||||
this.elevation = elevation;
|
||||
this.shadeLength = shadeLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the azimuth.
|
||||
*/
|
||||
public QuantityType<Angle> getAzimuth() {
|
||||
return new QuantityType<>(azimuth, Units.DEGREE_ANGLE);
|
||||
public State getAzimuth() {
|
||||
return Double.isNaN(azimuth) ? UnDefType.UNDEF : new QuantityType<>(azimuth, Units.DEGREE_ANGLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the azimuth.
|
||||
*/
|
||||
public void setAzimuth(double azimuth) {
|
||||
this.azimuth = azimuth;
|
||||
public double getAzimuthAsDouble() {
|
||||
return azimuth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the elevation.
|
||||
*/
|
||||
public QuantityType<Angle> getElevation() {
|
||||
return new QuantityType<>(elevation, Units.DEGREE_ANGLE);
|
||||
public State getElevation() {
|
||||
return Double.isNaN(elevation) ? UnDefType.UNDEF : new QuantityType<>(elevation, Units.DEGREE_ANGLE);
|
||||
}
|
||||
|
||||
public double getElevationAsDouble() {
|
||||
@@ -67,23 +65,10 @@ public class Position {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the elevation.
|
||||
* Returns the shade length ratio.
|
||||
*/
|
||||
public void setElevation(double elevation) {
|
||||
this.elevation = elevation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shade length.
|
||||
*/
|
||||
public double getShadeLength() {
|
||||
return shadeLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the shade length.
|
||||
*/
|
||||
public void setShadeLength(double shadeLength) {
|
||||
this.shadeLength = shadeLength;
|
||||
public State getShadeLength() {
|
||||
return Double.isNaN(elevation) ? UnDefType.UNDEF
|
||||
: elevation <= 0 ? UnDefType.NULL : new DecimalType(1d / MathUtils.tanDeg(elevation));
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -28,8 +28,7 @@ public class Sun extends RiseSet implements Planet {
|
||||
|
||||
private Map<SunPhaseName, Range> ranges = new HashMap<>();
|
||||
|
||||
private Position position = new Position();
|
||||
|
||||
private Position position = Position.NULL;
|
||||
private Zodiac zodiac = Zodiac.NULL;
|
||||
|
||||
private @Nullable Season season = null;
|
||||
|
||||
+2
-2
@@ -110,8 +110,8 @@ public class MoonCalcTest {
|
||||
moonCalc.setPositionalInfo(FEB_27_2019, AMSTERDAM_LATITUDE, AMSTERDAM_LONGITUDE, moon, TIME_ZONE, Locale.ROOT);
|
||||
|
||||
// expected result from heavens-above.com is Azimuth: 100.5, altitude -17
|
||||
assertEquals(100.5, moon.getPosition().getAzimuth().doubleValue(), ACCURACY_IN_DEGREE);
|
||||
assertEquals(-17, moon.getPosition().getElevation().doubleValue(), ACCURACY_IN_DEGREE);
|
||||
assertEquals(100.5, moon.getPosition().getAzimuthAsDouble(), ACCURACY_IN_DEGREE);
|
||||
assertEquals(-17, moon.getPosition().getElevationAsDouble(), ACCURACY_IN_DEGREE);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user