diff --git a/SAS/TMSS/backend/services/scheduling/lib/constraints.py b/SAS/TMSS/backend/services/scheduling/lib/constraints.py
index 6ba03a8b6996142098086a112437b8b2a86e97f9..249dca148bc38fdbce59fe6717f2a71e4f156aaa 100644
--- a/SAS/TMSS/backend/services/scheduling/lib/constraints.py
+++ b/SAS/TMSS/backend/services/scheduling/lib/constraints.py
@@ -28,7 +28,7 @@ These main methods are used in the dynamic_scheduler to pick the next best sched
 
 from datetime import datetime, timedelta
 from dateutil import parser
-from typing import Callable, Union
+from typing import Callable, Union, Tuple, Iterable
 from astropy.coordinates import Angle
 from astropy.coordinates.earth import EarthLocation
 import astropy.units
@@ -192,7 +192,7 @@ class ConstraintResult():
 
 
 @lru_cache(100, typed=False)
-def get_boundary_stations_from_list(stations: [str]) -> (str, str, str, str):
+def get_boundary_stations_from_list(stations: Tuple[str]) -> Tuple[str]:
     '''
     utility function to determine the stations at boundary locations. Meant to be used for constraint checks, since when
     constraints are met at these stations, this is typically also true at the other stations.
@@ -219,6 +219,11 @@ def get_boundary_stations_from_list(stations: [str]) -> (str, str, str, str):
     return most_northern, most_eastern, most_southern, most_western
 
 
+def get_unique_sorted_boundary_stations_or_cs002(stations: Iterable[str]) -> Tuple[str]:
+    boundary_stations = set(get_boundary_stations_from_list(tuple(stations))) or {'CS002'}
+    return tuple(sorted(list(boundary_stations)))
+
+
 def filter_scheduling_units_using_constraints(scheduling_units: [models.SchedulingUnitBlueprint], lower_bound: datetime, upper_bound: datetime, raise_if_interruped: Callable=noop, gridder: Gridder=None) -> [models.SchedulingUnitBlueprint]:
     """
     Filter the given scheduling_units by whether their constraints are met within the given timewindow.
@@ -243,7 +248,7 @@ def filter_scheduling_units_using_constraints(scheduling_units: [models.Scheduli
             assert(scheduling_unit.draft is not None)
             assert(scheduling_unit.scheduling_constraints_template is not None)
 
-            if can_run_within_station_reservations(scheduling_unit):
+            if can_run_within_station_reservations(scheduling_unit): # ToDo: submit proposed start time, do not rely on set scheduled_start/stop_time(s)
                 if can_run_within_timewindow_with_constraints(scheduling_unit, lower_bound, upper_bound, gridder):
                     if can_run_within_cycles_bounds(scheduling_unit, lower_bound, upper_bound):
                         runnable_scheduling_units.append(scheduling_unit)
@@ -296,10 +301,8 @@ def filter_scheduling_units_which_can_only_run_in_this_window(scheduling_units:
                 earliest_possible_start_time = min(earliest_possible_start_time, upper_bound)
 
                 if not can_run_after(scheduling_unit, earliest_possible_start_time, gridder=gridder):
-                    if not can_run_before(scheduling_unit, lower_bound, gridder=gridder):
-                        runnable_exclusive_in_this_window_scheduling_units.append(scheduling_unit)
-                    if lower_bound < datetime.utcnow() + timedelta(minutes=1):
-                        # no unit can run before 'now'
+                    if (not can_run_before(scheduling_unit, lower_bound, gridder=gridder) or
+                        (lower_bound < datetime.utcnow() + timedelta(minutes=1)) ): # no unit can run before 'now'
                         runnable_exclusive_in_this_window_scheduling_units.append(scheduling_unit)
 
             logger.info("filter_scheduling_units_which_can_only_run_in_this_window: checked unit [%d/%d] %.1f%% id=%d can %srun outside of window ['%s', '%s']",
@@ -316,7 +319,7 @@ def filter_scheduling_units_which_can_only_run_in_this_window(scheduling_units:
     return runnable_exclusive_in_this_window_scheduling_units
 
 
-def get_best_scored_scheduling_unit_scored_by_constraints(scheduling_units: [models.SchedulingUnitBlueprint], lower_bound_start_time:datetime, upper_bound_stop_time:datetime, coarse_gridder: Gridder, fine_gridder: Gridder) -> ScoredSchedulingUnit:
+def get_best_scored_scheduling_unit_scored_by_constraints(scheduling_units: [models.SchedulingUnitBlueprint], lower_bound_start_time:datetime, upper_bound_stop_time:datetime, coarse_gridder: Gridder, fine_gridder: Gridder, raise_if_interruped: Callable=noop) -> ScoredSchedulingUnit:
     """
     get the best scored schedulable scheduling_unit which can run withing the given time window from the given scheduling_units.
     :param lower_bound_start_time: evaluate and score the constrains at and after lower_bound_start_time. The returned unit has a start_time guaranteed at or after lower_bound_start_time.
@@ -338,9 +341,14 @@ def get_best_scored_scheduling_unit_scored_by_constraints(scheduling_units: [mod
 
         # Re-evaluate top 5(or less) with fine grid
         top_sorted_scored_scheduling_units_coarse = sorted_scored_scheduling_units_coarse[:5]
-        logger.info("get_best_scored_scheduling_unit_scored_by_constraints: scoring and sorting %d units at fine grid of %s[min]...", len(top_sorted_scored_scheduling_units_coarse), fine_gridder.grid_minutes)
-        top_scheduling_units = [x.scheduling_unit for x in top_sorted_scored_scheduling_units_coarse]
-        top_sorted_scored_scheduling_units_fine = sort_scheduling_units_scored_by_constraints(top_scheduling_units, lower_bound_start_time, upper_bound_stop_time, fine_gridder)
+        logger.info("get_best_scored_scheduling_unit_scored_by_constraints: (re)filtering, (re)scoring and sorting %d units at fine grid of %s[min]...", len(top_sorted_scored_scheduling_units_coarse), fine_gridder.grid_minutes)
+        top_scheduling_units_coarse = [x.scheduling_unit for x in top_sorted_scored_scheduling_units_coarse]
+
+        # First check if the top5 can also run when evaluated at the fine grid. There may be edge cases.
+        top_scheduling_units_fine = filter_scheduling_units_using_constraints(top_scheduling_units_coarse, lower_bound_start_time, upper_bound_stop_time, gridder=fine_gridder, raise_if_interruped=raise_if_interruped)
+
+        # compute te scores at the fine grid
+        top_sorted_scored_scheduling_units_fine = sort_scheduling_units_scored_by_constraints(top_scheduling_units_fine, lower_bound_start_time, upper_bound_stop_time, fine_gridder)
 
         _method_elapsed = datetime.utcnow() - _method_start_timestamp
         logger.debug("get_best_scored_scheduling_unit_scored_by_constraints: scored and sorted %d units (took %.1f[s])", len(scheduling_units), _method_elapsed.total_seconds())
@@ -775,8 +783,7 @@ def evaluate_sky_transit_constraint(scheduling_unit: models.SchedulingUnitBluepr
         task_proposed_start_time = proposed_start_time + target_obs_task.relative_start_time
         task_proposed_center_time = task_proposed_start_time + (target_obs_task.specified_duration / 2)
 
-        # TODO: determine transit opt/earliest times over all boundery stations
-        stations = ('CS002',) #set(get_boundary_stations_from_list(target_obs_task.specified_stations)) or ('CS002',)
+        stations = get_unique_sorted_boundary_stations_or_cs002(target_obs_task.specified_stations)
 
         # currently we only check at bounds and center, we probably want to add some more samples in between later on
         for pointing in transit_pointings:
@@ -840,7 +847,7 @@ def evaluate_sky_min_elevation_constraint(scheduling_unit: models.SchedulingUnit
             return result
 
         # limit stations to be evaluated to the edge stations
-        stations = set(get_boundary_stations_from_list(tuple(task.specified_stations))) or ('CS002',)
+        stations = get_unique_sorted_boundary_stations_or_cs002(tuple(task.specified_stations))
 
         # determine the min_elevation and stations depending on observation type
         pointings_and_min_elevations = []
@@ -869,14 +876,17 @@ def evaluate_sky_min_elevation_constraint(scheduling_unit: models.SchedulingUnit
 
         # currently we only check at bounds and center, we probably want to add some more samples in between later on
         for timestamp in (task_proposed_start_time, task_proposed_center_time, task_proposed_end_time):
-            for pointing, min_elevation in pointings_and_min_elevations:
-                gridded_timestamp = gridder.grid_time(timestamp)
-                station_target_rise_and_set_times = coordinates_timestamps_and_stations_to_target_rise_and_set(pointing=pointing,
-                                                                                                               timestamps=(gridded_timestamp,),
-                                                                                                               stations=tuple(stations),
-                                                                                                               angle_to_horizon=min_elevation,
-                                                                                                               n_grid_points=gridder.n_grid_points())
-                for station, target_rise_and_set_times in station_target_rise_and_set_times.items():
+            for station in stations:
+                for pointing, min_elevation in pointings_and_min_elevations:
+                    gridded_timestamp = gridder.grid_time(timestamp)
+                    station_target_rise_and_set_times = coordinates_timestamps_and_stations_to_target_rise_and_set(pointing=pointing,
+                                                                                                                   timestamps=(gridded_timestamp,),
+                                                                                                                   stations=(station,),
+                                                                                                                   angle_to_horizon=min_elevation,
+                                                                                                                   n_grid_points=gridder.n_grid_points())
+                    assert len(station_target_rise_and_set_times) == 1
+                    assert station in station_target_rise_and_set_times
+                    target_rise_and_set_times = station_target_rise_and_set_times[station]
                     assert len(target_rise_and_set_times) == 1
                     rise_and_set_time = target_rise_and_set_times[0]
                     if rise_and_set_time['rise'] is not None:
@@ -896,16 +906,17 @@ def evaluate_sky_min_elevation_constraint(scheduling_unit: models.SchedulingUnit
 
                     # check if constraint is met...
                     if rise_and_set_time['always_below_horizon'] or \
-                            (rise_and_set_time['rise'] is not None and timestamp < gridder.plus_margin(rise_and_set_time['rise'])) or \
-                            (rise_and_set_time['set'] is not None and timestamp > gridder.minus_margin(rise_and_set_time['set'])):
-                        # constraint not met. update result, and do early exit.
-                        result.score = 0
-                        result.evaluation_timestamp = gridded_timestamp
-                        result.optimal_start_time = None
+                            (rise_and_set_time['rise'] is not None and timestamp < gridder.minus_margin(rise_and_set_time['rise'])) or \
+                            (rise_and_set_time['set'] is not None and timestamp > gridder.plus_margin(rise_and_set_time['set'])):
                         elevation = compute_elevation(pointing, gridded_timestamp, station)
-                        result.message = "task_id=%s task_name='%s' station=%s elevation=%.3f[deg] < min_elevation=%.3f[deg] at '%s'" % (task.id, task.name, station, Angle(elevation, astropy.units.rad).deg, min_elevation.degree, gridded_timestamp)
-                        logger.debug(result)
-                        return result
+                        if elevation < min_elevation.rad:
+                            # constraint not met. update result, and do early exit.
+                            result.score = 0
+                            result.evaluation_timestamp = gridded_timestamp
+                            result.optimal_start_time = None
+                            result.message = "task_id=%s task_name='%s' station=%s target='%s' elevation=%.3f[deg] < min_elevation=%.3f[deg] at '%s'" % (task.id, task.name, station, pointing.target, Angle(elevation, astropy.units.rad).deg, min_elevation.degree, gridded_timestamp)
+                            logger.info(result)
+                            return result
 
     # for min_elevation there is no optimal start time.
     # any timestamp meeting the constraint is good enough.
@@ -1044,12 +1055,12 @@ def get_earliest_possible_start_time_for_sky_min_elevation(scheduling_unit: mode
     # do expensive search from lower_bound until 24 hours later with small steps
     # (sky constrains are (almost) cyclic over 24 hours).
     # first occurrence where min_elevation constraint is met is taken as rough estimate of earliest_possible_start_time
-    gridded_lower_bound = gridder.grid_time(lower_bound)
-    possible_start_time = gridded_lower_bound
+    at = get_at_constraint_timestamp(scheduling_unit)
+    possible_start_time = at or gridder.grid_time(lower_bound)
     if upper_bound is None:
-        upper_bound = lower_bound + timedelta(hours=24)
+        upper_bound = lower_bound + (scheduling_unit.specified_observation_duration if at else timedelta(hours=24))
     upper_bound = max(lower_bound, upper_bound)
-    while possible_start_time < upper_bound:
+    while possible_start_time <= upper_bound-scheduling_unit.specified_observation_duration:
         raise_if_interruped()
 
         result = evaluate_sky_min_elevation_constraint(scheduling_unit, possible_start_time, gridder=gridder)
@@ -1188,7 +1199,7 @@ def evaluate_daily_constraints(scheduling_unit: models.SchedulingUnitBlueprint,
 
     duration = scheduling_unit.specified_observation_duration
     proposed_end_time = proposed_start_time + duration
-    stations = set(get_boundary_stations_from_list(tuple(scheduling_unit.main_observation_stations))) or ('CS002',)
+    stations = get_unique_sorted_boundary_stations_or_cs002(tuple(scheduling_unit.main_observation_stations))
 
     # the sun rise/set events do not depend on the actual time-of-day, but only on the date.
     # so, use one timstamp for 'today'-noon, one for 'yesterday'-noon and one for 'tomorrow'-noon
@@ -1390,7 +1401,7 @@ def get_earliest_possible_start_time_for_time_constraints(scheduling_unit: model
                         earliest_possible_start_times.add(potential_earliest_possible)
                         break
 
-    if not earliest_possible_start_times and not constraints.get('time'):
+    if not earliest_possible_start_times and not (constraints.get('time') or constraints.get('time',{}).get('between') or constraints.get('time',{}).get('not_between')):
         # an empty time constraint means it can just run at/after lower_bound
         return lower_bound
 
@@ -1424,7 +1435,7 @@ def get_earliest_possible_start_time(scheduling_unit: models.SchedulingUnitBluep
     if at:
         # if there is an 'at' constraint, then that is always earliest_possible_start_time
         # however... we should also check if all other constraints are met. So, can it run at 'at'?
-        if can_run_at(scheduling_unit, at):
+        if can_run_at(scheduling_unit, at, gridder=gridder):
             return at
         return None
 
diff --git a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
index 97d463d7ea402d92443737909a12de2dc3bfc28f..f8cb43c17b339158ab9b587508045ac2c28ae17e 100644
--- a/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
+++ b/SAS/TMSS/backend/services/scheduling/lib/dynamic_scheduling.py
@@ -97,8 +97,8 @@ class Scheduler:
         self._scheduling_thread = None
         self._scheduling_thread_running = False
         self._do_schedule_event = Event()
-        self.search_gridder = Gridder(grid_minutes=Gridder.VERY_COARSE_TIME_GRID)
-        self.fine_gridder = Gridder(grid_minutes=Gridder.DEFAULT_TIME_GRID)
+        self.search_gridder = Gridder(grid_minutes=1*60)
+        self.fine_gridder = Gridder(grid_minutes=1)
         super().__init__()
         # make sure initial status is idle
         models.Subsystem.Activator('scheduler').deactivate()
@@ -359,14 +359,8 @@ class Scheduler:
 
         logger.info("find_best_next_schedulable_unit: units to score in window ['%s', '%s']: %s", lower_bound_start_time, upper_bound_stop_time, ','.join([str(su.id) for su in sorted(units_to_score, key=lambda x: x.id)]) or 'None')
 
-        #ToDo: TMSS-1745 Add unschedulable reasons
-        # implementation hint: subtract units_to_score from scheduling_units giving you the not_to_be_scheduled_units list
-        # then ask for each unit in this list if it can be run after lower_bound_start_time
-        # if not, call each evaluate_x_contraints method. If contraint not met, then you know which constraint is not met and why.
-        # return the correct reason as given in the ticket for each un-met constraint type.
-
         # from the filtered down list of units, compute the (weighted) scores, and return the best scoring one.
-        best_scored_scheduling_unit = get_best_scored_scheduling_unit_scored_by_constraints(units_to_score, lower_bound_start_time, upper_bound_stop_time, self.search_gridder, self.fine_gridder)
+        best_scored_scheduling_unit = get_best_scored_scheduling_unit_scored_by_constraints(units_to_score, lower_bound_start_time, upper_bound_stop_time, self.search_gridder, self.fine_gridder, raise_if_interruped=self._raise_if_triggered)
 
         _elapsed = datetime.utcnow() - _start_search_timestamp
 
@@ -383,10 +377,6 @@ class Scheduler:
         Overlapping existing scheduled units are unscheduled if their score is lower.
         :return: the scheduled scheduling unit.'''
 
-        # use relatively fine gridders for scheduling the upcoming unit.
-        self.search_gridder = Gridder(grid_minutes=1*60)
-        self.fine_gridder = Gridder(grid_minutes=1)
-
         # prepare queries for subsets of schedulable_units (django uses lazy evaluation, so don't worry about wasted queries)
         schedulable_units_triggered = get_triggered_schedulable_scheduling_units()
         schedulable_units_queue_A = get_dynamically_schedulable_scheduling_units(priority_queue=models.PriorityQueueType.objects.get(value=models.PriorityQueueType.Choices.A.value))
@@ -579,10 +569,6 @@ class Scheduler:
                 scheduling_unit.placed = False
                 scheduling_unit.save()
 
-        # use relatively coarser gridders for mid-term schedule. Just to get a rough idea.
-        self.search_gridder = Gridder(grid_minutes=3*60)
-        self.fine_gridder = Gridder(grid_minutes=15)
-
         priority_queue_A = models.PriorityQueueType.objects.get(value=models.PriorityQueueType.Choices.A.value)
         priority_queue_B = models.PriorityQueueType.objects.get(value=models.PriorityQueueType.Choices.B.value)
 
@@ -700,7 +686,7 @@ def mark_scheduling_units_for_inactive_projects_unschedulable(projects: [str]=No
             logger.info("marking unit id=%s status= %s project=%s pstate=%s", scheduling_unit.id, scheduling_unit.status, scheduling_unit.project.name, scheduling_unit.project.project_state.value)
             with transaction.atomic():
                 mark_independent_subtasks_in_scheduling_unit_blueprint_as_unschedulable(scheduling_unit, reason="project %s is not active"%(scheduling_unit.project.name,))
-                set_scheduling_unit_blueprint_start_times(scheduling_unit, first_start_time=round_to_second_precision(datetime.utcnow()))
+                set_scheduling_unit_blueprint_start_times(scheduling_unit, first_start_time=round_to_second_precision(get_at_constraint_timestamp(scheduling_unit) or datetime.utcnow()))
 
 
 def mark_unschedulable_scheduling_units_for_active_projects_schedulable(projects: [str]=None):
diff --git a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py
index 8b4585ec7f1fcee8441123b340c16b4b1c558c75..b97075f377c75d4f1213f9bf203afe2b5e10182d 100755
--- a/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py
+++ b/SAS/TMSS/backend/services/scheduling/test/t_dynamic_scheduling.py
@@ -1581,8 +1581,8 @@ class TestDynamicScheduling(BaseDynamicSchedulingTestCase):
                 ("constraint time.at='2029-12-31 00:00:00' falls outside of cycle bounds ['2030-01-01 00:00:00', '2030-01-07 00:00:00']", '',  {'scheduler': 'dynamic', 'time': {'at': (cycle.start - timedelta(hours=24)).isoformat()}}),
                 ("time constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", '',  {'scheduler': 'dynamic', 'time': {'before': (cycle.start - timedelta(hours=24)).isoformat()}}),
                 ("time constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", '',  {'scheduler': 'dynamic', 'time': {'after': (cycle.stop + timedelta(hours=24)).isoformat()}}),
-                ("sky min_elevation constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", "task_name='Observation' station=CS002 elevation=",  {'scheduler': 'dynamic', 'sky': {'min_elevation': {'target': 1.57}}}),
-                ("sky min_elevation constraint is not met at 2030-01-01 00:00:00", "task_name='Observation' station=CS002 elevation=",  {'scheduler': 'fixed_time', 'sky': {'min_elevation': {'target': 1.57}}, 'time': {'at': '2030-01-01T00:00:00Z'}}),
+                ("sky min_elevation constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", "task_name='Observation' station=CS002 target='_target_name_' elevation=",  {'scheduler': 'dynamic', 'sky': {'min_elevation': {'target': 1.57}}}),
+                ("sky min_elevation constraint is not met at 2030-01-01 00:00:00", "task_name='Observation' station=CS002 target='_target_name_' elevation=",  {'scheduler': 'fixed_time', 'sky': {'min_elevation': {'target': 1.57}}, 'time': {'at': '2030-01-01T00:00:00Z'}}),
                 ("sky min_distance constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-08 00:00:00", 'to body=sun < min_distance=149.9',  {'scheduler': 'dynamic', 'sky': {'min_distance': {'sun': 150 * 3.1415/180.0}}}),
                 ("sky min_distance constraint is not met at 2030-01-01 00:00:00", 'to body=sun < min_distance=149.9',  {'scheduler': 'fixed_time', 'sky': {'min_distance': {'sun': 150 * 3.1415/180.0}}, 'time': {'at': '2030-01-01T00:00:00Z'}}),
                 ("sky transit_offset constraint is not met anywhere between 2030-01-01 00:00:00 and 2030-01-01 07:00:00", '',  {'scheduler': 'dynamic', 'sky': {'transit_offset': {'from': -900, 'to': 900}}, 'time': {'between': [{'from': '2030-01-01T00:00:00Z', 'to': '2030-01-01T07:00:00Z'}]}}),
@@ -1609,8 +1609,8 @@ class TestDynamicScheduling(BaseDynamicSchedulingTestCase):
             # Assert the scheduling_unit has not been scheduled and that it has the correct expected unschedulable_reason
             scheduling_unit_blueprint.refresh_from_db()
             self.assertEqual('unschedulable', scheduling_unit_blueprint.status.value)
-            self.assertTrue(scheduling_unit_blueprint.unschedulable_reason.startswith(expected_reason_start))
-            self.assertTrue(expected_specific_reason_part in scheduling_unit_blueprint.unschedulable_reason)
+            self.assertTrue(scheduling_unit_blueprint.unschedulable_reason.startswith(expected_reason_start), msg="expected: %s\nactual:%s"%(expected_reason_start, scheduling_unit_blueprint.unschedulable_reason))
+            self.assertTrue(expected_specific_reason_part in scheduling_unit_blueprint.unschedulable_reason, msg="expected: %s\nactual:%s"%(expected_specific_reason_part, scheduling_unit_blueprint.unschedulable_reason))
 
     def test_clear_unschedulable_reason_TMSS_1881_bugfix(self):
         '''Test if the unschedulable reason is cleared for cleanup task.
@@ -1621,20 +1621,26 @@ class TestDynamicScheduling(BaseDynamicSchedulingTestCase):
         scheduling_set = models.SchedulingSet.objects.create(**SchedulingSet_test_data(project=project))
         strategy_template = models.SchedulingUnitObservingStrategyTemplate.get_latest(name="IM HBA - 1 Beam")
         su_draft = create_scheduling_unit_draft_from_observing_strategy_template(strategy_template, scheduling_set=scheduling_set)
+        su_draft.scheduling_constraints_doc['scheduler'] = 'dynamic'
+        # by default, allow very loose sky constraints which can basically run anywhere
+        su_draft.scheduling_constraints_doc['sky']['transit_offset'] = {'from': -12 * 60 * 60, 'to': 12 * 60 * 60}
+        su_draft.scheduling_constraints_doc['sky']['min_elevation'] = {'target': 0, 'calibrator': 0}
+        su_draft.scheduling_constraints_doc['sky']['min_distance'] = {'sun': 0, 'moon': 0, 'jupiter': 0}
+        su_draft.save()
+
+        su_blueprint = create_scheduling_unit_blueprint_and_tasks_and_subtasks_from_scheduling_unit_draft(su_draft)
 
         # start the dynamic_scheduling_service, which includes eventmessage handling, and a running scheduler
         with BusListenerJanitor(create_dynamic_scheduling_service()):
             # at scheduler startup, all units are evaluated for schedulability.
             # assert the scheduling_unit has been marked as unschedulable
-            su_blueprint = create_scheduling_unit_blueprint_and_tasks_and_subtasks_from_scheduling_unit_draft(su_draft)
-
-            # now wait and poll until unit is unschedulable, or timeout
+            # wait and poll until unit is unschedulable, or timeout
             su_blueprint = wait_for_scheduling_unit_blueprint_status(su_blueprint.id, models.SchedulingUnitStatus.Choices.UNSCHEDULABLE.value, timeout=60)
             self.assertEqual(models.SchedulingUnitStatus.Choices.UNSCHEDULABLE.value, su_blueprint.status.value)
 
             # all subtasks should have a unschedulable_reason
             self.assertTrue(all([s.unschedulable_reason is not None for s in su_blueprint.subtasks.all()]))
-            self.assertTrue(all([s.unschedulable_reason == 'project is not active' for s in su_blueprint.subtasks.filter(specifications_template__type__value='observation').all()]))
+            self.assertTrue(all([s.unschedulable_reason == ('project %s is not active'%(project.name,)) for s in su_blueprint.subtasks.filter(specifications_template__type__value='observation').all()]))
             self.assertTrue(all([s.unschedulable_reason == 'predecessor is unschedulable' for s in su_blueprint.subtasks.exclude(specifications_template__type__value='observation').all()]))
 
             # check tasks and unit as well
@@ -2171,11 +2177,11 @@ class TestDynamicScheduling(BaseDynamicSchedulingTestCase):
         best_scored_scheduling_unit = self.scheduler.find_best_next_schedulable_unit([su_blueprint], datetime(2023, 2, 16, 23, 0),  datetime(2023, 2, 17, 11, 0))
         self.assertIsNone(best_scored_scheduling_unit)
 
-        # now determine the unschedulable reason..., and check that it is indeed incorrect as the bug reports.
-        su_blueprint = determine_unschedulable_reason_and_mark_unschedulable_if_needed(su_blueprint, datetime(2023, 2, 16, 23, 0),  datetime(2023, 2, 17, 11, 0), gridder=self.scheduler.search_gridder)
+        # now determine the unschedulable reason..., and check that it now correct after the bugfix.
+        su_blueprint = determine_unschedulable_reason_and_mark_unschedulable_if_needed(su_blueprint, datetime(2023, 2, 16, 23, 0),  datetime(2023, 2, 17, 11, 0), gridder=self.scheduler.fine_gridder)
         self.assertEqual(models.SchedulingUnitStatus.Choices.UNSCHEDULABLE.value, su_blueprint.status.value)
         logger.info(su_blueprint.unschedulable_reason)
-        # confirming bug: FR606 is falsely in the reason, and IE613 is not.
+        # bug fixed?: FR606 should not be in reason anymore, and IE613 should.
         self.assertFalse("FR606" in su_blueprint.unschedulable_reason)
         self.assertTrue("IE613" in su_blueprint.unschedulable_reason)