2017-04-30 14:39:46 -06:00
|
|
|
import csv
|
2017-05-28 13:23:17 -06:00
|
|
|
from datetime import datetime, timedelta
|
2017-04-30 14:39:46 -06:00
|
|
|
|
2017-03-31 02:32:03 -06:00
|
|
|
from orbit import satellite
|
|
|
|
|
2017-11-13 03:27:11 -07:00
|
|
|
from django.db.models import Count, Max
|
2017-04-30 14:39:46 -06:00
|
|
|
from django.conf import settings
|
2017-11-13 03:27:11 -07:00
|
|
|
from django.core.cache import cache
|
2017-04-30 14:39:46 -06:00
|
|
|
from django.core.mail import send_mail
|
2018-01-06 04:25:23 -07:00
|
|
|
from django.contrib.sites.models import Site
|
2017-04-30 14:39:46 -06:00
|
|
|
from django.template.loader import render_to_string
|
2017-09-08 09:42:38 -06:00
|
|
|
from django.utils.timezone import make_aware
|
2018-08-18 18:43:02 -06:00
|
|
|
from influxdb import InfluxDBClient
|
2017-04-30 14:39:46 -06:00
|
|
|
|
|
|
|
from db.base.models import Satellite, DemodData
|
2017-11-13 03:27:11 -07:00
|
|
|
from db.base.utils import calculate_statistics
|
2017-05-29 13:11:09 -06:00
|
|
|
from db.celery import app
|
2018-08-18 18:43:02 -06:00
|
|
|
from db.base.utils import decode_data
|
2017-03-31 02:32:03 -06:00
|
|
|
|
|
|
|
|
2017-05-29 13:11:09 -06:00
|
|
|
@app.task(task_ignore_result=False)
|
2017-03-31 02:32:03 -06:00
|
|
|
def check_celery():
|
|
|
|
"""Dummy celery task to check that everything runs smoothly."""
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2017-05-29 13:11:09 -06:00
|
|
|
@app.task
|
2017-03-31 02:32:03 -06:00
|
|
|
def update_all_tle():
|
2017-04-30 14:39:46 -06:00
|
|
|
"""Task to update all satellite TLEs"""
|
2017-03-31 02:32:03 -06:00
|
|
|
satellites = Satellite.objects.all()
|
|
|
|
|
|
|
|
for obj in satellites:
|
|
|
|
try:
|
|
|
|
sat = satellite(obj.norad_cat_id)
|
2018-07-14 11:42:17 -06:00
|
|
|
except Exception:
|
2017-03-31 02:32:03 -06:00
|
|
|
continue
|
|
|
|
|
|
|
|
tle = sat.tle()
|
|
|
|
obj.tle1 = tle[1]
|
|
|
|
obj.tle2 = tle[2]
|
|
|
|
obj.save()
|
2017-04-30 14:39:46 -06:00
|
|
|
|
|
|
|
|
2017-05-29 13:11:09 -06:00
|
|
|
@app.task
|
2017-05-28 13:23:17 -06:00
|
|
|
def export_frames(norad, email, uid, period=None):
|
2017-04-30 14:39:46 -06:00
|
|
|
"""Task to export satellite frames in csv."""
|
2017-05-28 13:23:17 -06:00
|
|
|
now = datetime.utcnow()
|
|
|
|
if period:
|
|
|
|
if period == '1':
|
2017-09-08 09:42:38 -06:00
|
|
|
q = now - timedelta(days=7)
|
2017-05-28 13:23:17 -06:00
|
|
|
suffix = 'week'
|
|
|
|
else:
|
2017-09-08 09:42:38 -06:00
|
|
|
q = now - timedelta(days=30)
|
2017-05-28 13:23:17 -06:00
|
|
|
suffix = 'month'
|
2017-09-08 09:42:38 -06:00
|
|
|
q = make_aware(q)
|
2017-05-28 13:23:17 -06:00
|
|
|
frames = DemodData.objects.filter(satellite__norad_cat_id=norad,
|
|
|
|
timestamp__gte=q)
|
|
|
|
else:
|
|
|
|
frames = DemodData.objects.filter(satellite__norad_cat_id=norad)
|
|
|
|
suffix = 'all'
|
|
|
|
filename = '{0}-{1}-{2}-{3}.csv'.format(norad, uid, now.strftime('%Y%m%dT%H%M%SZ'), suffix)
|
2017-04-30 14:39:46 -06:00
|
|
|
filepath = '{0}/download/{1}'.format(settings.MEDIA_ROOT, filename)
|
|
|
|
with open(filepath, 'w') as f:
|
2017-05-29 13:11:09 -06:00
|
|
|
writer = csv.writer(f, delimiter='|')
|
2017-04-30 14:39:46 -06:00
|
|
|
for obj in frames:
|
2017-05-29 13:11:09 -06:00
|
|
|
writer.writerow([obj.timestamp.strftime('%Y-%m-%d %H:%M:%S'),
|
|
|
|
obj.display_frame()])
|
2017-04-30 14:39:46 -06:00
|
|
|
|
|
|
|
# Notify user
|
2018-01-06 04:25:23 -07:00
|
|
|
site = Site.objects.get_current()
|
2017-04-30 14:39:46 -06:00
|
|
|
subject = '[satnogs] Your request for exported frames is ready!'
|
|
|
|
template = 'emails/exported_frames.txt'
|
|
|
|
data = {
|
2018-01-06 04:25:23 -07:00
|
|
|
'url': '{0}{1}download/{2}'.format(site.domain,
|
2017-05-28 13:23:17 -06:00
|
|
|
settings.MEDIA_URL, filename),
|
2017-04-30 14:39:46 -06:00
|
|
|
'norad': norad
|
|
|
|
}
|
|
|
|
message = render_to_string(template, {'data': data})
|
|
|
|
send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, [email], False)
|
2017-11-13 03:27:11 -07:00
|
|
|
|
|
|
|
|
|
|
|
@app.task
|
|
|
|
def cache_statistics():
|
|
|
|
statistics = calculate_statistics()
|
|
|
|
cache.set('stats_transmitters', statistics, 60 * 60 * 2)
|
|
|
|
|
|
|
|
satellites = Satellite.objects \
|
|
|
|
.values('name', 'norad_cat_id') \
|
|
|
|
.annotate(count=Count('telemetry_data'),
|
|
|
|
latest_payload=Max('telemetry_data__timestamp')) \
|
|
|
|
.order_by('-count')
|
|
|
|
cache.set('stats_satellites', satellites, 60 * 60 * 2)
|
|
|
|
|
|
|
|
observers = DemodData.objects \
|
|
|
|
.values('observer') \
|
|
|
|
.annotate(count=Count('observer'),
|
|
|
|
latest_payload=Max('timestamp')) \
|
|
|
|
.order_by('-count')
|
|
|
|
cache.set('stats_observers', observers, 60 * 60 * 2)
|
2018-08-18 18:43:02 -06:00
|
|
|
|
|
|
|
|
|
|
|
# resets all decoded data and changes the is_decoded flag back to False
|
|
|
|
# THIS IS VERY DISTRUCTIVE, but the expectation is that a decode_all_data would
|
|
|
|
# follow.
|
|
|
|
@app.task
|
|
|
|
def reset_decoded_data(norad):
|
|
|
|
"""DESTRUCTIVE: deletes decoded data from db and/or influxdb"""
|
|
|
|
frames = DemodData.objects.filter(satellite__norad_cat_id=norad)
|
|
|
|
for frame in frames:
|
|
|
|
frame.payload_decoded = ''
|
|
|
|
frame.is_decoded = False
|
|
|
|
frame.save()
|
|
|
|
if settings.USE_INFLUX:
|
|
|
|
client = InfluxDBClient(settings.INFLUX_HOST, settings.INFLUX_PORT,
|
|
|
|
settings.INFLUX_USER, settings.INFLUX_PASS,
|
|
|
|
settings.INFLUX_DB)
|
|
|
|
client.query('DROP SERIES FROM /.*/ WHERE \"norad\" = \'{0}\''
|
|
|
|
.format(norad))
|
|
|
|
|
|
|
|
|
|
|
|
# decode data for a satellite, and a given time frame (if provided). If not
|
|
|
|
# provided it is expected that we want to try decoding all frames in the db.
|
|
|
|
@app.task
|
|
|
|
def decode_all_data(norad):
|
|
|
|
"""Task to trigger a full decode of data for a satellite."""
|
|
|
|
decode_data(norad)
|
|
|
|
|
|
|
|
|
|
|
|
@app.task
|
|
|
|
def decode_recent_data():
|
|
|
|
"""Task to trigger a partial/recent decode of data for all satellites."""
|
|
|
|
satellites = Satellite.objects.all()
|
|
|
|
|
|
|
|
for obj in satellites:
|
|
|
|
try:
|
|
|
|
decode_data(obj.norad_cat_id, period=1)
|
|
|
|
except Exception:
|
|
|
|
continue
|