From 9b6af71d7acd0209c07f1e842d17fcbfc4561ea6 Mon Sep 17 00:00:00 2001 From: Alain Klotz Date: Fri, 29 Sep 2023 14:21:53 +0200 Subject: [PATCH] Update version Scheduler --- src/core/pyros_django/majordome/agent/Agent.py | 8 ++++---- src/core/pyros_django/scheduling/A_Scheduler.py | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 2 files changed, 98 insertions(+), 18 deletions(-) diff --git a/src/core/pyros_django/majordome/agent/Agent.py b/src/core/pyros_django/majordome/agent/Agent.py index 44a8ae7..d233cd5 100755 --- a/src/core/pyros_django/majordome/agent/Agent.py +++ b/src/core/pyros_django/majordome/agent/Agent.py @@ -3482,13 +3482,13 @@ class Agent: if loginfo: log.info(self._oc['config'].fn.fcontexts_human()) - def ephem_target2night(self, target:str) -> dict: + def ephem_target2night(self, target:str, date: str="now") -> dict: eph = Ephemeris() eph.set_home(self._oc['config'].getHome()) fcontext0 = self._oc['config'].fn.fcontext # --- Build the path and file name of the sun ephemeris self._oc['config'].fn.fcontext = "pyros_eph" - night = self._oc['config'].fn.date2night("now") + night = self._oc['config'].fn.date2night(date) operiod = Period.objects.exploitation_period() if operiod == None: log.info("No period valid in the database") @@ -3506,8 +3506,8 @@ class Agent: "unit": self._oc['config'].unit_name, "target": target } - fname = self._fn.naming_set(fn_param) - eph_file = self._fn.joinabs(fname) + fname = self._oc['config'].fn.naming_set(fn_param) + eph_file = self._oc['config'].fn.joinabs(fname) # --- Compute the sun ephemeris if needed. Save it as pickle. if not os.path.exists(eph_file): ephem_target = eph.target2night(target, night, None, None) diff --git a/src/core/pyros_django/scheduling/A_Scheduler.py b/src/core/pyros_django/scheduling/A_Scheduler.py index adfe8f5..3c13afc 100755 --- a/src/core/pyros_django/scheduling/A_Scheduler.py +++ b/src/core/pyros_django/scheduling/A_Scheduler.py @@ -127,6 +127,9 @@ class A_Scheduler(Agent): self.check_contexts(True) log.info(f"{self._fn.longitude=}") + # TBD duskelev a parametrer from obsconfig (yml) + self._duskelev = -7 + # === Status of routine processing self._routine_running = self.RUNNING_NOTHING log.debug("end init()") @@ -229,6 +232,14 @@ class A_Scheduler(Agent): subdir = info['subdir'] # --- Get the night night = info['night'] + # --- Get ephemeris informations of the night and initialize quotas + night_info = self.update_sun_moon_ephems() + quota_total_period = night_info['total'][1] + quota_total_night_start = night_info[night][0] + quota_total_night_end = night_info[night][1] + self.dprint(f"{quota_total_period=}") + self.dprint(f"{quota_total_night_start=}") + self.dprint(f"{quota_total_night_end=}") # --- Build the wildcard to list the sequences wildcard = os.path.join(rootdir, subdir, "*.p") self.dprint(f"{wildcard=}") @@ -529,18 +540,16 @@ class A_Scheduler(Agent): rootdir = info['rootdir'] subdir = info['subdir'] - # --- Prepare ephemeris object - # TBD duskelev a parametrer from obsconfig (yml) - duskelev = -7 - eph = guitastro.Ephemeris() - eph.set_home(self.config.getHome()) - - # --- Build the path and file name of the sun ephemeris + # --- Read or create the sun ephemeris ephem_sun = self.ephem_target2night("sun") - # --- Build the path and file name of the moon ephemeris + # --- Read or create the moon ephemeris ephem_moon = self.ephem_target2night("moon") + # --- Prepare ephemeris object + eph = guitastro.Ephemeris() + eph.set_home(self.config.getHome()) + # --- Horizon (TBD get from config) self.dprint("Debut _create_seq_1 Horizon") hor = guitastro.Horizon(eph.home) @@ -613,7 +622,7 @@ class A_Scheduler(Agent): #print(f"{k} : TRY") errors = [] try: - ephem = eph.target2night(seq["sequence"]["config_attributes"]["target"], info['night'], ephem_sun, ephem_moon, preference=seq['sequence']['start_expo_pref'], duskelev=duskelev, horizon=hor, duration=duration) + ephem = eph.target2night(seq["sequence"]["config_attributes"]["target"], info['night'], ephem_sun, ephem_moon, preference=seq['sequence']['start_expo_pref'], duskelev=self._duskelev, horizon=hor, duration=duration) except ValueError: errors.append("Target value is not valid") except guitastro.ephemeris.EphemerisException as ephemException: @@ -630,7 +639,80 @@ class A_Scheduler(Agent): def load_sequence(self): sequence = "" return sequence + + def update_sun_moon_ephems(self): + """Update the files in the ephems folder. + The file 'duration.pickle' contains the start, end for each night and other informations to make quota computations. + + Check if the file 'duration.pickle' exists in the ephem/period directory. + If yes, returns the contents of the 'duration.pickle' file. + If not, check each ephemeris file existance for Sun and Moon and compute them if needed. + + Returns: + Dictionary with night string as key. Values are a list of integers: + + * total1: Cumulative sum of seconds of previous night durations at the start of the night. + * total2: Cumulative sum of seconds of previous night durations at the end of the night. + * total_night: Number of seconds available during this night. + * sec1: Index of seconds for the start of the night. + * sec2: Index of seconds for the end of the night. + + """ + + # --- Get the period object + operiod = Period.objects.exploitation_period() + + # --- Get the period ID + period_id = operiod.get_period_id_as_str() + + # --- Select the context of ephemeris + fcontext0 = self._oc['config'].fn.fcontext + self._oc['config'].fn.fcontext = "pyros_eph" + + # --- Check if durations.pickle file exists + rootdir = self._oc['config'].fn.rootdir + filename = os.path.join(rootdir, period_id, "durations.pickle") + self.dprint(f"Read {filename=}") + if os.path.exists(filename): + self._oc['config'].fn.fcontext = fcontext0 + return pickle.load(open(filename, "wb")) + + # --- Get the period limit dates jd1, jd2 + self.dprint(f"{dir(operiod)=}") + d = operiod.start_date.isoformat() + night_start = d[0:4]+d[5:7]+d[8:10] + jd1, _ = self.config.fn.night2date(night_start) + d = operiod.end_date.isoformat() + night_end = d[0:4]+d[5:7]+d[8:10] + jd2, _ = self.config.fn.night2date(night_end) + self.dprint(f"{night_start=} {night_end=}") + self.dprint(f"{jd1=} {jd2=}") + + # --- Loop over dates of the period to create ephems + targets = ['sun', 'moon'] + jd = jd1 + 0.1 + total1 = 0 + night_info = {} + while jd < jd2: + night = self._oc['config'].fn.date2night(jd) + for target in targets: + self.dprint(f"{night=} {target=}") + ephem = self.ephem_target2night(target, jd) + if target == "sun": + ks = np.where(ephem['alt'] < self._duskelev) + total_night = len(ks[0]) + total2 = total1 + total_night + sec1 = ks[0][0] + sec2 = ks[0][-1] + night_info[night] = [int(total1), int(total2), int(total_night), sec1, sec2] + total1 = total2 + jd += 1 + night_info['total'] = [0, int(total2), int(total2), -1, -1] + self.dprint(f"Write {filename=}") + pickle.dump(night_info, open(filename, "wb")) + return night_info + def get_infos(self): self._fn.fcontext = "pyros_seq" rootdir = self._fn.rootdir @@ -639,11 +721,9 @@ class A_Scheduler(Agent): log.info("No period valid in the database") self._routine_running = self.RUNNING_NOTHING return - period_id = str(operiod.id) - if len(str(operiod.id)) < 3: - while len(period_id) < 3: - period_id = "0" + period_id - period_id = "P" + period_id + # retourne un str -> id de la période sous le format Pxxx + period_id = operiod.get_period_id_as_str() + night_id = self._fn.date2night("now") subdir = os.path.join(period_id, night_id) dico = {} -- libgit2 0.21.2