Skip to content

Commit

Permalink
#154 (3)
Browse files Browse the repository at this point in the history
use skyfield instead of astropy
  • Loading branch information
dostuffthatmatters committed May 3, 2023
1 parent 2820457 commit d7b20a7
Show file tree
Hide file tree
Showing 7 changed files with 138 additions and 60 deletions.
23 changes: 11 additions & 12 deletions packages/core/modules/enclosure_control.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,18 +236,17 @@ def auto_set_power_spectrometer(self) -> None:
"""

current_sun_elevation = utils.Astronomy.get_current_sun_elevation(self.config)
min_power_elevation = (
self.config["general"]["min_sun_elevation"] - 1
) * utils.Astronomy.units.deg

if current_sun_elevation is not None:
sun_is_above_minimum = current_sun_elevation >= min_power_elevation
if sun_is_above_minimum and (not self.plc_state["power"]["spectrometer"]):
self.plc_interface.set_power_spectrometer(True)
logger.info("Powering up the spectrometer.")
if (not sun_is_above_minimum) and self.plc_state["power"]["spectrometer"]:
self.plc_interface.set_power_spectrometer(False)
logger.info("Powering down the spectrometer.")
min_power_elevation = self.config["general"]["min_sun_elevation"] - 1
sun_is_above_minimum = current_sun_elevation >= min_power_elevation
spectrometer_is_powered = self.plc_state["power"]["spectrometer"]

if sun_is_above_minimum and (not spectrometer_is_powered):
self.plc_interface.set_power_spectrometer(True)
logger.info("Powering up the spectrometer.")

if (not sun_is_above_minimum) and spectrometer_is_powered:
self.plc_interface.set_power_spectrometer(False)
logger.info("Powering down the spectrometer.")

def sync_cover_to_measurement_status(self) -> None:
"""Checks for flank changes in parameter measurement_should_be_running.
Expand Down
5 changes: 1 addition & 4 deletions packages/core/modules/measurement_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,7 @@ def _get_automatic_decision(self) -> bool:
min_sun_elevation = max(
self._CONFIG["general"]["min_sun_elevation"], triggers["min_sun_elevation"]
)
sun_above_threshold = current_sun_elevation > (
min_sun_elevation * utils.Astronomy.units.deg
)
if sun_above_threshold:
if current_sun_elevation > min_sun_elevation:
logger.debug("Sun angle is above threshold.")
else:
logger.debug("Sun angle is below threshold.")
Expand Down
31 changes: 15 additions & 16 deletions packages/core/modules/opus_measurement.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,26 +258,34 @@ def opus_application_running(self) -> bool:
except _win32ui.error:
return False

def low_sun_angle_present(self) -> bool:
def sun_angle_is_too_low(self) -> bool:
"""Checks defined sun angle in config. Closes OPUS at the end of the day to start up fresh
the next day."""

assert sys.platform == "win32"

sun_angle_is_low: bool = utils.Astronomy.get_current_sun_elevation(
self._CONFIG
).is_within_bounds(
None, self._CONFIG["general"]["min_sun_elevation"] * utils.Astronomy.units.deg
return (
utils.Astronomy.get_current_sun_elevation(self._CONFIG)
< self._CONFIG["general"]["min_sun_elevation"]
)
return sun_angle_is_low

def automated_process_handling(self) -> None:
"""Start OPUS.exe if not running and sun angle conditions satisfied.
Shuts down OPUS.exe if running and sun angle conditions not satisfied.
"""
assert sys.platform == "win32"

if not self.low_sun_angle_present():
if self.sun_angle_is_too_low():
# Close OPUS if running
if self.opus_application_running():
logger.debug("Requesting OPUS night shutdown.")
# CLOSE_OPUS needs all macros closed to work. stop_macro() is
# called just in case
self.stop_macro()
time.sleep(5)
self.close_opus()

else:
# start OPUS if not currently running
if not self.opus_application_running():
logger.info("Start OPUS.")
Expand All @@ -287,15 +295,6 @@ def automated_process_handling(self) -> None:
self.load_experiment()
# returns to give OPUS time to start until next call of run()
return
if self.low_sun_angle_present():
# Close OPUS if running
if self.opus_application_running():
logger.debug("Requesting OPUS night shutdown.")
# CLOSE_OPUS needs all macros closed to work. stop_macro() is
# called just in case
self.stop_macro()
time.sleep(5)
self.close_opus()

def wait_for_opus_startup(self) -> None:
"""Checks for OPUS to be running. Breaks out of the loop after a defined time."""
Expand Down
9 changes: 3 additions & 6 deletions packages/core/threads/helios_thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,9 @@ def main(headless: bool = False) -> None:
edge_fraction_history.set_max_size(new_max_history_size)

# sleep while sun angle is too low
if (not headless) and utils.Astronomy.get_current_sun_elevation(
_CONFIG
).is_within_bounds(
None,
_CONFIG["general"]["min_sun_elevation"] * utils.Astronomy.units.deg,
):
current_sun_elevation = utils.Astronomy.get_current_sun_elevation(_CONFIG)
min_sun_elevation = _CONFIG["general"]["min_sun_elevation"]
if (not headless) and (current_sun_elevation > min_sun_elevation):
logger.debug("Current sun elevation below minimum: Waiting 5 minutes")
if current_state is not None:
interfaces.StateInterface.update(
Expand Down
36 changes: 16 additions & 20 deletions packages/core/utils/astronomy.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,26 @@
from typing import Any
import astropy.coordinates as astropy_coordinates
import astropy.time as astropy_time
import astropy.units as astropy_units
from typing import Optional
import skyfield.api
from packages.core import types


# TODO: replace this with a better library
_PLANETS = skyfield.api.load("de421.bsp")
_EARTH = _PLANETS["earth"]
_SUN = _PLANETS["Sun"]


class Astronomy:
"""Provides a method to compute the current sun elevation
based on the coordinates from the CamTracker config file."""

units = astropy_units

@staticmethod
def get_current_sun_elevation(config: types.ConfigDict) -> Any:
def get_current_sun_elevation(config: types.ConfigDict) -> float:
"""Computes current sun elevation in degree, based on the
coordinates from the CamTracker config file."""

with open(config["camtracker"]["config_path"], "r") as f:
_lines = f.readlines()

# find $1 marker
_marker_line_index = None
_marker_line_index: Optional[int] = None
for n, line in enumerate(_lines):
if line == "$1\n":
_marker_line_index = n
Expand All @@ -33,14 +30,13 @@ def get_current_sun_elevation(config: types.ConfigDict) -> Any:
lon = float(_lines[_marker_line_index + 2].strip())
alt = float(_lines[_marker_line_index + 3].strip())

now = astropy_time.Time.now()

altaz = astropy_coordinates.AltAz(
location=astropy_coordinates.EarthLocation.from_geodetic(
height=alt, lat=lat, lon=lon
),
obstime=now,
current_time = skyfield.api.load.timescale().now()
current_position = _EARTH + skyfield.api.wgs84.latlon(
latitude_degrees=lat,
longitude_degrees=lon,
elevation_m=alt,
)
sun = astropy_coordinates.get_sun(now)
sun_angle_deg = sun.transform_to(altaz).alt
return sun_angle_deg

sun_pos = current_position.at(current_time).observe(_SUN).apparent()
altitude, _, _ = sun_pos.altaz()
return float(altitude.degrees)
90 changes: 89 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ tqdm = "4.65.0"
colorama = "0.4.6"
deepdiff = "6.3.0"
tum-esm-utils = "1.3.0"
skyfield = "^1.46"

[tool.poetry.group.dev.dependencies]
pytest = "7.2.2"
Expand Down Expand Up @@ -58,7 +59,8 @@ module = [
"snap7",
"snap7.*",
"deepdiff",
"psutil"
"psutil",
"skyfield.*"
]
ignore_missing_imports = true

Expand Down

0 comments on commit d7b20a7

Please sign in to comment.