diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py index 607273e7c9f438c01d81c5a90d077e7e79b3bd95..2b968bf0913cf065246ceed216a2220d001b2873 100644 --- a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py +++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py @@ -732,9 +732,9 @@ class Migration(migrations.Migration): ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')), ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')), ('time_offset', models.IntegerField(default=60, help_text='Time offset of start of second task with respect to start of first task.')), - ('first', models.ForeignKey(help_text='First Task Draft to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='first_to_connect', to='tmssapp.TaskDraft')), + ('first', models.ForeignKey(help_text='First Task Draft to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='first_scheduling_relation', to='tmssapp.TaskDraft')), ('placement', models.ForeignKey(help_text='Task scheduling relation placement.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.SchedulingRelationPlacement')), - ('second', models.ForeignKey(help_text='Second Task Draft to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='second_to_connect', to='tmssapp.TaskDraft')), + ('second', models.ForeignKey(help_text='Second Task Draft to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='second_scheduling_relation', to='tmssapp.TaskDraft')), ], options={ 'abstract': False, @@ -748,9 +748,9 @@ class Migration(migrations.Migration): ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')), ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')), ('time_offset', models.IntegerField(default=60, help_text='Time offset of start of second task with respect to start of first task.')), - ('first', models.ForeignKey(help_text='First Task Blueprint to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='first_to_connect', to='tmssapp.TaskBlueprint')), + ('first', models.ForeignKey(help_text='First Task Blueprint to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='first_scheduling_relation', to='tmssapp.TaskBlueprint')), ('placement', models.ForeignKey(default='after', help_text='Task scheduling relation placement.', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.SchedulingRelationPlacement')), - ('second', models.ForeignKey(help_text='Second Task Blueprint to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='second_to_connect', to='tmssapp.TaskBlueprint')), + ('second', models.ForeignKey(help_text='Second Task Blueprint to connect.', on_delete=django.db.models.deletion.CASCADE, related_name='second_scheduling_relation', to='tmssapp.TaskBlueprint')), ], options={ 'abstract': False, diff --git a/SAS/TMSS/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/src/tmss/tmssapp/models/specification.py index 35128abc3daa97d7f9ece42c0e53ac2e0efcaa8c..7d98fdc123cf9dc29fc93055904ccb5f6e637ace 100644 --- a/SAS/TMSS/src/tmss/tmssapp/models/specification.py +++ b/SAS/TMSS/src/tmss/tmssapp/models/specification.py @@ -545,7 +545,7 @@ class TaskDraft(NamedCommon): def relative_start_time(self) -> datetime.timedelta: '''return the earliest relative start time of all subtasks of this task ''' - scheduling_relations = list(self.first_to_connect.all()) + list(self.second_to_connect.all()) + scheduling_relations = list(self.first_scheduling_relation.all()) + list(self.second_scheduling_relation.all()) for scheduling_relation in scheduling_relations: if scheduling_relation.first.id == self.id and scheduling_relation.placement.value == "after": previous_related_task_draft = TaskDraft.objects.get(id=scheduling_relation.second.id) @@ -664,7 +664,7 @@ class TaskBlueprint(NamedCommon): def relative_start_time(self) -> datetime.timedelta: '''return the earliest relative start time of all subtasks of this task ''' - scheduling_relations = list(self.first_to_connect.all()) + list(self.second_to_connect.all()) + scheduling_relations = list(self.first_scheduling_relation.all()) + list(self.second_scheduling_relation.all()) for scheduling_relation in scheduling_relations: if scheduling_relation.first.id == self.id and scheduling_relation.placement.value == "after": previous_related_task_blueprint = TaskBlueprint.objects.get(id=scheduling_relation.second.id) @@ -756,8 +756,8 @@ class TaskRelationBlueprint(BasicCommon): class TaskSchedulingRelationBlueprint(BasicCommon): - first = ForeignKey('TaskBlueprint', related_name='first_to_connect', on_delete=CASCADE, help_text='First Task Blueprint to connect.') - second = ForeignKey('TaskBlueprint', related_name='second_to_connect', on_delete=CASCADE, help_text='Second Task Blueprint to connect.') + first = ForeignKey('TaskBlueprint', related_name='first_scheduling_relation', on_delete=CASCADE, help_text='First Task Blueprint to connect.') + second = ForeignKey('TaskBlueprint', related_name='second_scheduling_relation', on_delete=CASCADE, help_text='Second Task Blueprint to connect.') placement = ForeignKey('SchedulingRelationPlacement', null=False, default="after", on_delete=PROTECT, help_text='Task scheduling relation placement.') time_offset = IntegerField(default=60, help_text='Time offset of start of second task with respect to start of first task.') @@ -770,8 +770,8 @@ class TaskSchedulingRelationBlueprint(BasicCommon): class TaskSchedulingRelationDraft(BasicCommon): - first = ForeignKey('TaskDraft', related_name='first_to_connect', on_delete=CASCADE, help_text='First Task Draft to connect.') - second = ForeignKey('TaskDraft', related_name='second_to_connect', on_delete=CASCADE, help_text='Second Task Draft to connect.') + first = ForeignKey('TaskDraft', related_name='first_scheduling_relation', on_delete=CASCADE, help_text='First Task Draft to connect.') + second = ForeignKey('TaskDraft', related_name='second_scheduling_relation', on_delete=CASCADE, help_text='Second Task Draft to connect.') placement = ForeignKey('SchedulingRelationPlacement', null=False, on_delete=PROTECT, help_text='Task scheduling relation placement.') time_offset = IntegerField(default=60, help_text='Time offset of start of second task with respect to start of first task.') diff --git a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py index 0a3584ed2c7a82e0415ce201a60c4d2e58151fe0..fd6a1284babfff6bda958d69a11e62d5a1909ce6 100644 --- a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py +++ b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py @@ -317,7 +317,7 @@ class TaskDraftSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.TaskDraft fields = '__all__' - extra_fields = ['task_blueprints', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration', 'relative_start_time', 'relative_stop_time'] + extra_fields = ['task_blueprints', 'produced_by', 'consumed_by', 'first_scheduling_relation', 'second_scheduling_relation', 'duration', 'relative_start_time', 'relative_stop_time'] class TaskBlueprintSerializer(RelationalHyperlinkedModelSerializer): @@ -338,7 +338,7 @@ class TaskBlueprintSerializer(RelationalHyperlinkedModelSerializer): class Meta: model = models.TaskBlueprint fields = '__all__' - extra_fields = ['subtasks', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration', 'start_time', 'stop_time', 'relative_start_time', 'relative_stop_time'] + extra_fields = ['subtasks', 'produced_by', 'consumed_by', 'first_scheduling_relation', 'second_scheduling_relation', 'duration', 'start_time', 'stop_time', 'relative_start_time', 'relative_stop_time'] class TaskRelationDraftSerializer(RelationalHyperlinkedModelSerializer): diff --git a/SAS/TMSS/src/tmss/tmssapp/subtasks.py b/SAS/TMSS/src/tmss/tmssapp/subtasks.py index e25e23b52d48bf75d1fa30b62b578ed12274f01d..d9970ff6c7dd8680e022b78b1a50acc0e4e7d9d0 100644 --- a/SAS/TMSS/src/tmss/tmssapp/subtasks.py +++ b/SAS/TMSS/src/tmss/tmssapp/subtasks.py @@ -635,7 +635,7 @@ def get_previous_related_task_blueprint_with_time_offset(task_blueprint): previous_related_task_blueprint = None time_offset = 0 - scheduling_relations = list(task_blueprint.first_to_connect.all()) + list(task_blueprint.second_to_connect.all()) + scheduling_relations = list(task_blueprint.first_scheduling_relation.all()) + list(task_blueprint.second_scheduling_relation.all()) for scheduling_relation in scheduling_relations: if scheduling_relation.first.id == task_blueprint.id and scheduling_relation.placement.value == "after": previous_related_task_blueprint = TaskBlueprint.objects.get(id=scheduling_relation.second.id) @@ -700,10 +700,10 @@ def schedule_observation_subtask(observation_subtask: Subtask): observation_subtask.save() # step 1a: check start/stop times + # start time should be known. If not raise. Then the user and/or scheduling service should supply a properly calculated/estimated start_time first. if observation_subtask.start_time is None: - next_start_time = calculate_start_time(observation_subtask) - logger.info("observation id=%s has no starttime. assigned default: %s", observation_subtask.pk, formatDatetime(next_start_time)) - observation_subtask.start_time = next_start_time + raise SubtaskSchedulingException("Cannot schedule subtask id=%d type=%s because it has no start_time" % (observation_subtask.pk, + observation_subtask.specifications_template.type)) if observation_subtask.stop_time is None: duration_in_sec = observation_subtask.task_blueprint.specifications_doc["duration"] diff --git a/SAS/TMSS/src/tmss/tmssapp/tasks.py b/SAS/TMSS/src/tmss/tmssapp/tasks.py index dd7771dd333f8d03ff2caa7c3963ba1e399362e0..ea0272de57483e9b71b9fb42c3592d4eff286eb1 100644 --- a/SAS/TMSS/src/tmss/tmssapp/tasks.py +++ b/SAS/TMSS/src/tmss/tmssapp/tasks.py @@ -13,6 +13,7 @@ import os from lofar.common.json_utils import add_defaults_to_json_object_for_schema import logging +from datetime import datetime logger = logging.getLogger(__name__) @@ -180,7 +181,7 @@ def create_task_blueprint_from_task_draft(task_draft: models.TaskDraft) -> model task_relation_blueprint.pk, producing_task_blueprint.pk, consuming_task_blueprint.pk,) # Do the same 'trick' for Task Scheduling Relation Draft to Blueprint - task_draft_scheduling_relations = list(task_draft.first_to_connect.all()) + list(task_draft.second_to_connect.all()) + task_draft_scheduling_relations = list(task_draft.first_scheduling_relation.all()) + list(task_draft.second_scheduling_relation.all()) for task_scheduling_relation_draft in task_draft_scheduling_relations: for first_task_blueprint in task_scheduling_relation_draft.first.task_blueprints.all(): for second_task_blueprint in task_scheduling_relation_draft.second.task_blueprints.all():