Add additional TLE sources via python-satellitetle
parent
8cb0f12077
commit
c405f781c4
|
@ -1,5 +1,3 @@
|
|||
from orbit import satellite
|
||||
|
||||
from rest_framework import viewsets, mixins, status
|
||||
from rest_framework.parsers import FormParser, FileUploadParser
|
||||
from rest_framework.permissions import AllowAny
|
||||
|
@ -9,6 +7,7 @@ from django.core.files.base import ContentFile
|
|||
|
||||
from db.api import serializers, filters, pagination
|
||||
from db.base.models import Mode, Satellite, Transmitter, DemodData
|
||||
from db.base.tasks import update_satellite
|
||||
|
||||
|
||||
class ModeView(viewsets.ReadOnlyModelViewSet):
|
||||
|
@ -40,24 +39,15 @@ class TelemetryView(viewsets.ModelViewSet, mixins.CreateModelMixin):
|
|||
def create(self, request, *args, **kwargs):
|
||||
data = {}
|
||||
|
||||
create_satellite = False
|
||||
norad_cat_id = request.data.get('noradID')
|
||||
try:
|
||||
data['satellite'] = Satellite.objects.get(norad_cat_id=norad_cat_id).id
|
||||
except Satellite.DoesNotExist:
|
||||
create_satellite = True
|
||||
|
||||
if create_satellite:
|
||||
if not Satellite.objects.get(norad_cat_id=norad_cat_id).exists():
|
||||
try:
|
||||
sat = satellite(norad_cat_id)
|
||||
except IndexError:
|
||||
update_satellite(norad_cat_id, update_name=True, update_tle=True)
|
||||
except LookupError:
|
||||
return Response(status=status.HTTP_400_BAD_REQUEST)
|
||||
else:
|
||||
tle = sat.tle()
|
||||
obj = Satellite.objects.create(norad_cat_id=norad_cat_id, name=tle[0],
|
||||
tle1=tle[1], tle2=tle[2])
|
||||
data['satellite'] = obj
|
||||
|
||||
data['satellite'] = Satellite.objects.get(norad_cat_id=norad_cat_id).id
|
||||
data['station'] = request.data.get('source')
|
||||
timestamp = request.data.get('timestamp')
|
||||
data['timestamp'] = timestamp
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
from django.core.management.base import BaseCommand
|
||||
|
||||
from db.base.models import Satellite
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Delete selected Satellites'
|
||||
|
||||
def add_arguments(self, parser):
|
||||
# Positional arguments
|
||||
parser.add_argument('norad_ids',
|
||||
nargs='+',
|
||||
metavar='<norad id>')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
for norad_id in options['norad_ids']:
|
||||
try:
|
||||
Satellite.objects.get(norad_cat_id=norad_id).delete()
|
||||
self.stdout.write('Deleted satellite {}.'.format(norad_id))
|
||||
continue
|
||||
except Exception:
|
||||
self.stderr.write('Satellite with Identifier {} does not exist'.format(norad_id))
|
|
@ -1,8 +1,6 @@
|
|||
from orbit import satellite
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from db.base.models import Satellite
|
||||
from db.base.tasks import update_satellite
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
|
@ -10,40 +8,14 @@ class Command(BaseCommand):
|
|||
|
||||
def add_arguments(self, parser):
|
||||
# Positional arguments
|
||||
parser.add_argument('satellite_identifiers',
|
||||
parser.add_argument('norad_ids',
|
||||
nargs='+',
|
||||
metavar='<Satellite Identifier>')
|
||||
|
||||
# Named (optional) arguments
|
||||
parser.add_argument(
|
||||
'--delete',
|
||||
action='store_true',
|
||||
dest='delete',
|
||||
default=False,
|
||||
help='Delete Satellite'
|
||||
)
|
||||
metavar='<norad id>')
|
||||
|
||||
def handle(self, *args, **options):
|
||||
for item in options['satellite_identifiers']:
|
||||
if options['delete']:
|
||||
try:
|
||||
Satellite.objects.get(norad_cat_id=item).delete()
|
||||
self.stdout.write('Satellite {}: deleted'.format(item))
|
||||
continue
|
||||
except Exception:
|
||||
raise CommandError('Satellite with Identifier {} does not exist'.format(item))
|
||||
|
||||
for norad_id in options['norad_ids']:
|
||||
try:
|
||||
sat = satellite(item)
|
||||
except Exception:
|
||||
raise CommandError('Satellite with Identifier {} does not exist'.format(item))
|
||||
|
||||
try:
|
||||
obj = Satellite.objects.get(norad_cat_id=item)
|
||||
except Exception:
|
||||
obj = Satellite(norad_cat_id=item)
|
||||
|
||||
obj.name = sat.name()
|
||||
obj.save()
|
||||
|
||||
self.stdout.write('fetched data for {}: {}'.format(obj.norad_cat_id, obj.name))
|
||||
update_satellite(int(norad_id), update_name=True, update_tle=False)
|
||||
except LookupError:
|
||||
self.stderr.write('Satellite {} not found in Celestrak'.format(norad_id))
|
||||
continue
|
||||
|
|
|
@ -1,28 +1,10 @@
|
|||
from orbit import satellite
|
||||
|
||||
from django.core.management.base import BaseCommand
|
||||
|
||||
from db.base.models import Satellite
|
||||
from db.base.tasks import update_all_tle
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = 'Update TLEs for existing Satellites'
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
satellites = Satellite.objects.all()
|
||||
|
||||
for obj in satellites:
|
||||
try:
|
||||
sat = satellite(obj.norad_cat_id)
|
||||
except Exception:
|
||||
self.stdout.write(('Satellite {} with Identifier {} does '
|
||||
'not exist').format(obj.name, obj.norad_cat_id))
|
||||
continue
|
||||
|
||||
tle = sat.tle()
|
||||
obj.tle1 = tle[1]
|
||||
obj.tle2 = tle[2]
|
||||
obj.save()
|
||||
self.stdout.write(('Satellite {} with Identifier {} '
|
||||
'found [updated]').format(obj.name, obj.norad_cat_id))
|
||||
update_all_tle()
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.11 on 2018-09-19 00:28
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('base', '0002_demoddata_is_decoded'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='satellite',
|
||||
name='tle_source',
|
||||
field=models.CharField(blank=True, max_length=300),
|
||||
),
|
||||
]
|
|
@ -68,6 +68,7 @@ class Satellite(models.Model):
|
|||
help_text='Ideally: 250x250')
|
||||
tle1 = models.CharField(max_length=200, blank=True)
|
||||
tle2 = models.CharField(max_length=200, blank=True)
|
||||
tle_source = models.CharField(max_length=300, blank=True)
|
||||
status = models.CharField(choices=zip(SATELLITE_STATUS, SATELLITE_STATUS),
|
||||
max_length=10, default='alive')
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import csv
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from orbit import satellite
|
||||
|
||||
from django.db.models import Count, Max
|
||||
from django.conf import settings
|
||||
from django.core.cache import cache
|
||||
|
@ -12,6 +10,11 @@ from django.template.loader import render_to_string
|
|||
from django.utils.timezone import make_aware
|
||||
from influxdb import InfluxDBClient
|
||||
|
||||
from sgp4.earth_gravity import wgs72
|
||||
from sgp4.io import twoline2rv
|
||||
|
||||
from satellite_tle import fetch_tle_from_celestrak, fetch_tles
|
||||
|
||||
from db.base.models import Satellite, DemodData
|
||||
from db.base.utils import calculate_statistics
|
||||
from db.celery import app
|
||||
|
@ -24,21 +27,76 @@ def check_celery():
|
|||
pass
|
||||
|
||||
|
||||
@app.task
|
||||
def update_satellite(norad_id, update_name=True, update_tle=True):
|
||||
"""Task to update the name and/or the tle of a satellite, or create a
|
||||
new satellite in the db if no satellite with given norad_id can be found"""
|
||||
|
||||
tle = fetch_tle_from_celestrak(norad_id)
|
||||
|
||||
satellite_created = False
|
||||
try:
|
||||
satellite = Satellite.objects.get(norad_cat_id=norad_id)
|
||||
except Satellite.DoesNotExist:
|
||||
satellite_created = True
|
||||
satellite = Satellite(norad_cat_id=norad_id)
|
||||
|
||||
if update_name:
|
||||
satellite.name = tle[0]
|
||||
|
||||
if update_tle:
|
||||
satellite.tle_source = 'Celestrak (satcat)'
|
||||
satellite.tle1 = tle[1]
|
||||
satellite.tle2 = tle[2]
|
||||
|
||||
satellite.save()
|
||||
|
||||
if satellite_created:
|
||||
print('Created satellite {}: {}'.format(satellite.norad_cat_id, satellite.name))
|
||||
else:
|
||||
print('Updated satellite {}: {}'.format(satellite.norad_cat_id, satellite.name))
|
||||
|
||||
|
||||
@app.task
|
||||
def update_all_tle():
|
||||
"""Task to update all satellite TLEs"""
|
||||
satellites = Satellite.objects.all()
|
||||
|
||||
for obj in satellites:
|
||||
try:
|
||||
sat = satellite(obj.norad_cat_id)
|
||||
except Exception:
|
||||
satellites = Satellite.objects.all()
|
||||
norad_ids = list(int(sat.norad_cat_id) for sat in satellites)
|
||||
|
||||
tles = fetch_tles(norad_ids)
|
||||
|
||||
missing_norad_ids = []
|
||||
for satellite in satellites:
|
||||
norad_id = satellite.norad_cat_id
|
||||
|
||||
if norad_id not in tles.keys():
|
||||
# No TLE available for this satellite
|
||||
missing_norad_ids.append(norad_id)
|
||||
continue
|
||||
|
||||
tle = sat.tle()
|
||||
obj.tle1 = tle[1]
|
||||
obj.tle2 = tle[2]
|
||||
obj.save()
|
||||
source, tle = tles[norad_id]
|
||||
|
||||
if satellite.tle1 and satellite.tle2:
|
||||
current_sat = twoline2rv(satellite.tle1, satellite.tle2, wgs72)
|
||||
new_sat = twoline2rv(tle[1], tle[2], wgs72)
|
||||
|
||||
if new_sat.epoch < current_sat.epoch:
|
||||
# Epoch of new TLE is larger then the TLE already in the db
|
||||
continue
|
||||
|
||||
satellite.tle_source = source
|
||||
satellite.tle1 = tle[1]
|
||||
satellite.tle2 = tle[2]
|
||||
satellite.save()
|
||||
|
||||
print('Updated TLE for {}: {} from {}'.format(norad_id,
|
||||
satellite.name,
|
||||
source))
|
||||
|
||||
for norad_id in missing_norad_ids:
|
||||
satellite = satellites.get(norad_cat_id=norad_id)
|
||||
print('NO TLE found for {}: {}'.format(norad_id, satellite.name))
|
||||
|
||||
|
||||
@app.task
|
||||
|
|
|
@ -30,7 +30,7 @@ Markdown==2.6.11
|
|||
mysqlclient==1.3.12
|
||||
oauthlib==2.0.6
|
||||
olefile==0.45.1
|
||||
orbit@git+https://gitlab.com/librespacefoundation/orbit.git@db463c2d261365485c157f2c86233aaf44e577a2
|
||||
satellitetle==0.4.0
|
||||
Pillow==5.0.0
|
||||
pyephem==3.7.6.0
|
||||
python-dateutil==2.7.3
|
||||
|
@ -46,6 +46,7 @@ requests-cache==0.4.13
|
|||
requests-oauthlib==0.8.0
|
||||
rjsmin==1.0.12
|
||||
satnogsdecoders==0.1
|
||||
sgp4==1.4
|
||||
shortuuid==0.5.0
|
||||
simplejson==3.16.0
|
||||
six==1.11.0
|
||||
|
|
Loading…
Reference in New Issue