From c54cb05df5fee10f663b89004d54be8deb473cb2 Mon Sep 17 00:00:00 2001 From: Marvin Gaube Date: Sat, 13 Aug 2022 18:26:36 +0200 Subject: [PATCH 1/6] Some parts of time prognosing --- production_control/models.py | 46 +++++++++++++++++++++++++++++++ production_control/serializers.py | 5 ++++ production_control/upstream.py | 2 -- production_control/views.py | 5 ++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/production_control/models.py b/production_control/models.py index c17f907..8feab71 100644 --- a/production_control/models.py +++ b/production_control/models.py @@ -1,5 +1,6 @@ from django.db import models import uuid +import datetime # example json: https://pretalx.margau.net/dtjhhnfm2022/schedule/export/schedule.json @@ -45,3 +46,48 @@ class EndCondition(models.IntegerChoices): actual_duration = models.IntegerField(blank=True, null=True) start = models.IntegerField(choices=StartCondition.choices, default=0) end = models.IntegerField(choices=EndCondition.choices, default=0) + + @property + def planned_end(self): + end = self.planned_start + datetime.timedelta(0, self.planned_duration) + return end + + @property + def actual_end(self): + end = 0 + if self.actual_start and self.actual_duration: + end = self.actual_start + datetime.timedelta(0, self.actual_duration) + return end + + @property + def delay_seconds(self): + delay_seconds = 0 + i = 0 + all_performances = Performance.objects.filter(venue=self.venue).order_by("planned_start") + print(all_performances) + # loop over all performances to find delay + while i < len(all_performances): + p = all_performances[i] + i+=1 + if p.id == self.id: + break + + # default case: no actual data available + # first case: we are running, have no actual end yet, so the delay + if p.actual_start: + delay_seconds = (p.actual_start-p.planned_start).total_seconds() + # if we are already done, set the end delay + if p.actual_end: + delay_seconds = (p.actual_end-p.planned_end).total_seconds() + + # todo: Check earlier/later talks + + return delay_seconds + + @property + def estimated_start(self): + # if we already have an actual start, that is our estimated start + if self.actual_start: + return self.actual_start + + return self.planned_start + datetime.timedelta(0, self.delay_seconds) \ No newline at end of file diff --git a/production_control/serializers.py b/production_control/serializers.py index 3dc33f1..298527c 100644 --- a/production_control/serializers.py +++ b/production_control/serializers.py @@ -13,6 +13,11 @@ class Meta: fields = '__all__' class PerformanceSerializer(serializers.HyperlinkedModelSerializer): + planned_end = serializers.ReadOnlyField() + actual_end = serializers.ReadOnlyField() + estimated_start = serializers.ReadOnlyField() + delay_seconds = serializers.ReadOnlyField() + class Meta: model = Performance fields = '__all__' diff --git a/production_control/upstream.py b/production_control/upstream.py index 72049e6..5f04169 100644 --- a/production_control/upstream.py +++ b/production_control/upstream.py @@ -28,9 +28,7 @@ def update(event): venue = Venue.objects.get(upstream_name = roomname) for upstream_perf in room: p_start = parser.parse(upstream_perf["start"]) - print(p_start) p_duration = timeparse(upstream_perf["duration"])*60 - print(p_duration) p, created = Performance.objects.update_or_create( upstream_uuid = upstream_perf["guid"], defaults={ diff --git a/production_control/views.py b/production_control/views.py index b7397a3..57be885 100644 --- a/production_control/views.py +++ b/production_control/views.py @@ -27,6 +27,11 @@ class VenueViewSet(viewsets.ModelViewSet): queryset = Venue.objects.all() serializer_class = VenueSerializer permission_classes = [permissions.AllowAny] + @action(detail=True) + def current_timeline(self, request, pk): + # todo: Error Handling + serializer = PerformanceSerializer(Performance.objects.filter(venue=self.get_object().id).order_by("planned_start"),many=True,context={'request': request}) + return Response(serializer.data) class PerformanceViewSet(viewsets.ModelViewSet): """ From 423e88703a4d1f3c302edbacf8ed9b3536a25e40 Mon Sep 17 00:00:00 2001 From: Marvin Gaube Date: Sat, 13 Aug 2022 20:02:23 +0200 Subject: [PATCH 2/6] Fix time duration --- production_control/models.py | 39 +++++++++++++++++++++++-------- production_control/serializers.py | 1 + 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/production_control/models.py b/production_control/models.py index 8feab71..0fe8f4a 100644 --- a/production_control/models.py +++ b/production_control/models.py @@ -57,6 +57,7 @@ def actual_end(self): end = 0 if self.actual_start and self.actual_duration: end = self.actual_start + datetime.timedelta(0, self.actual_duration) + print(end) return end @property @@ -64,14 +65,10 @@ def delay_seconds(self): delay_seconds = 0 i = 0 all_performances = Performance.objects.filter(venue=self.venue).order_by("planned_start") - print(all_performances) # loop over all performances to find delay while i < len(all_performances): p = all_performances[i] - i+=1 - if p.id == self.id: - break - + # default case: no actual data available # first case: we are running, have no actual end yet, so the delay if p.actual_start: @@ -79,15 +76,37 @@ def delay_seconds(self): # if we are already done, set the end delay if p.actual_end: delay_seconds = (p.actual_end-p.planned_end).total_seconds() - - # todo: Check earlier/later talks + + # if we are not the first check + if i > 0 and all_performances[i-1]: + # if our start is later or equal than the previous estimated end, no delay is left + if p.planned_start >= all_performances[i-1].estimated_end: + delay_seconds = 0 + # otherwise, the delay is the time delay between the prev. end and our planned start + else: + delay_seconds = (all_performances[i-1].estimated_end - p.planned_start).total_seconds() + + # if this is our searched performance, stop here + if p.id == self.id: + return delay_seconds + + i+=1 + print(delay_seconds) return delay_seconds @property def estimated_start(self): + ret = 0 # if we already have an actual start, that is our estimated start if self.actual_start: - return self.actual_start - - return self.planned_start + datetime.timedelta(0, self.delay_seconds) \ No newline at end of file + ret = self.actual_start + else: + ret = self.planned_start + datetime.timedelta(0, self.delay_seconds) + return ret + + @property + def estimated_end(self): + if self.actual_end: + return self.actual_end + return self.planned_end + datetime.timedelta(0, self.delay_seconds) \ No newline at end of file diff --git a/production_control/serializers.py b/production_control/serializers.py index 298527c..4742b5f 100644 --- a/production_control/serializers.py +++ b/production_control/serializers.py @@ -16,6 +16,7 @@ class PerformanceSerializer(serializers.HyperlinkedModelSerializer): planned_end = serializers.ReadOnlyField() actual_end = serializers.ReadOnlyField() estimated_start = serializers.ReadOnlyField() + estimated_end = serializers.ReadOnlyField() delay_seconds = serializers.ReadOnlyField() class Meta: From 1c55815b290ae6921bf404c89c9a887ff8c39fa9 Mon Sep 17 00:00:00 2001 From: Marvin Gaube Date: Sat, 13 Aug 2022 20:03:14 +0200 Subject: [PATCH 3/6] Remove Prints --- production_control/models.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/production_control/models.py b/production_control/models.py index 0fe8f4a..5c0b5d3 100644 --- a/production_control/models.py +++ b/production_control/models.py @@ -57,7 +57,6 @@ def actual_end(self): end = 0 if self.actual_start and self.actual_duration: end = self.actual_start + datetime.timedelta(0, self.actual_duration) - print(end) return end @property @@ -92,7 +91,6 @@ def delay_seconds(self): i+=1 - print(delay_seconds) return delay_seconds @property From 857a1b8089f7b21c9c4cbbdbbf6f45a19425d9ec Mon Sep 17 00:00:00 2001 From: Marvin Gaube Date: Sat, 13 Aug 2022 20:30:10 +0200 Subject: [PATCH 4/6] Fix actual end --- production_control/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/production_control/models.py b/production_control/models.py index 5c0b5d3..083bec2 100644 --- a/production_control/models.py +++ b/production_control/models.py @@ -54,7 +54,7 @@ def planned_end(self): @property def actual_end(self): - end = 0 + end = None if self.actual_start and self.actual_duration: end = self.actual_start + datetime.timedelta(0, self.actual_duration) return end From 122c622fcdc18c43361f0d6952bc9b30b8ae8135 Mon Sep 17 00:00:00 2001 From: Marvin Gaube Date: Sat, 13 Aug 2022 20:53:14 +0200 Subject: [PATCH 5/6] Update production_control/models.py Co-authored-by: Sohalt --- production_control/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/production_control/models.py b/production_control/models.py index 083bec2..b3be7cc 100644 --- a/production_control/models.py +++ b/production_control/models.py @@ -65,7 +65,7 @@ def delay_seconds(self): i = 0 all_performances = Performance.objects.filter(venue=self.venue).order_by("planned_start") # loop over all performances to find delay - while i < len(all_performances): + for p in all_performances: p = all_performances[i] # default case: no actual data available From 741ee04f886fe052d8aa37f9a6a0e503b55d4091 Mon Sep 17 00:00:00 2001 From: Marvin Gaube Date: Sat, 13 Aug 2022 20:56:00 +0200 Subject: [PATCH 6/6] Update Models --- production_control/models.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/production_control/models.py b/production_control/models.py index b3be7cc..bb948c3 100644 --- a/production_control/models.py +++ b/production_control/models.py @@ -69,7 +69,7 @@ def delay_seconds(self): p = all_performances[i] # default case: no actual data available - # first case: we are running, have no actual end yet, so the delay + # first case: we are running, have no actual end yet, so the delay is the start delay if p.actual_start: delay_seconds = (p.actual_start-p.planned_start).total_seconds() # if we are already done, set the end delay @@ -95,7 +95,6 @@ def delay_seconds(self): @property def estimated_start(self): - ret = 0 # if we already have an actual start, that is our estimated start if self.actual_start: ret = self.actual_start