1
0
Fork 0
satnogs-network/network/base/stats.py

107 lines
3.9 KiB
Python
Raw Normal View History

import math
from django.core.cache import cache
from django.db.models import Case, IntegerField, Sum, When
from django.utils.timezone import now
from network.base.models import Observation
def transmitter_stats_by_uuid(uuid):
stats = cache.get('tr-{0}-stats'.format(uuid))
if stats is None:
# Sum - Case - When should be replaced with Count and filter when we move to Django 2.*
# more at https://docs.djangoproject.com/en/2.2/ref/models/conditional-expressions in
# "Conditional aggregation" section.
stats = Observation.objects.filter(
transmitter_uuid=uuid
).exclude(
vetted_status='failed'
).aggregate(
good=Sum(
Case(When(vetted_status='good', then=1),
output_field=IntegerField())
),
bad=Sum(
Case(When(vetted_status='bad', then=1),
output_field=IntegerField())
),
unvetted=Sum(
Case(When(vetted_status='unknown',
end__lte=now(), then=1),
output_field=IntegerField())
),
future=Sum(
Case(When(vetted_status='unknown',
end__gt=now(), then=1),
output_field=IntegerField())
)
)
cache.set('tr-{0}-stats'.format(uuid), stats, 3600)
total_count = 0
unvetted_count = 0 if stats['unvetted'] is None else stats['unvetted']
future_count = 0 if stats['future'] is None else stats['future']
good_count = 0 if stats['good'] is None else stats['good']
bad_count = 0 if stats['bad'] is None else stats['bad']
total_count = unvetted_count + future_count + good_count + bad_count
unvetted_rate = 0
future_rate = 0
success_rate = 0
bad_rate = 0
if total_count:
unvetted_rate = math.trunc(10000 * (float(unvetted_count) / float(total_count))) / 100.0
future_rate = math.trunc(10000 * (float(future_count) / float(total_count))) / 100.0
success_rate = math.trunc(10000 * (float(good_count) / float(total_count))) / 100.0
bad_rate = math.trunc(10000 * (float(bad_count) / float(total_count))) / 100.0
return {
'total_count': total_count,
'unvetted_count': unvetted_count,
'future_count': future_count,
'good_count': good_count,
'bad_count': bad_count,
'unvetted_rate': unvetted_rate,
'future_rate': future_rate,
'success_rate': success_rate,
'bad_rate': bad_rate
}
def satellite_stats_by_transmitter_list(transmitter_list):
total_count = 0
unvetted_count = 0
future_count = 0
good_count = 0
bad_count = 0
unvetted_rate = 0
future_rate = 0
success_rate = 0
bad_rate = 0
for transmitter in transmitter_list:
transmitter_stats = transmitter_stats_by_uuid(transmitter['uuid'])
total_count += transmitter_stats['total_count']
unvetted_count += transmitter_stats['unvetted_count']
future_count += transmitter_stats['future_count']
good_count += transmitter_stats['good_count']
bad_count += transmitter_stats['bad_count']
if total_count:
unvetted_rate = math.trunc(10000 * (float(unvetted_count) / float(total_count))) / 100.0
future_rate = math.trunc(10000 * (float(future_count) / float(total_count))) / 100.0
success_rate = math.trunc(10000 * (float(good_count) / float(total_count))) / 100.0
bad_rate = math.trunc(10000 * (float(bad_count) / float(total_count))) / 100.0
return {
'total_count': total_count,
'unvetted_count': unvetted_count,
'future_count': future_count,
'good_count': good_count,
'bad_count': bad_count,
'unvetted_rate': unvetted_rate,
'future_rate': future_rate,
'success_rate': success_rate,
'bad_rate': bad_rate
}