Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Time estimation algorithm #3

Merged
merged 6 commits into from
Aug 13, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions production_control/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.db import models
import uuid
import datetime

# example json: https://pretalx.margau.net/dtjhhnfm2022/schedule/export/schedule.json

Expand Down Expand Up @@ -45,3 +46,65 @@ 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
margau marked this conversation as resolved.
Show resolved Hide resolved
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")
# loop over all performances to find delay
while i < len(all_performances):
margau marked this conversation as resolved.
Show resolved Hide resolved
p = all_performances[i]

# default case: no actual data available
# first case: we are running, have no actual end yet, so the delay
margau marked this conversation as resolved.
Show resolved Hide resolved
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()

# 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

return delay_seconds

@property
def estimated_start(self):
ret = 0
margau marked this conversation as resolved.
Show resolved Hide resolved
# if we already have an actual start, that is our estimated start
if self.actual_start:
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)
6 changes: 6 additions & 0 deletions production_control/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ class Meta:
fields = '__all__'

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:
model = Performance
fields = '__all__'
2 changes: 0 additions & 2 deletions production_control/upstream.py
Original file line number Diff line number Diff line change
Expand Up @@ -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={
Expand Down
5 changes: 5 additions & 0 deletions production_control/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand Down