1
0
Fork 0
satnogs-db/db/base/models.py

200 lines
6.9 KiB
Python
Raw Normal View History

import json
2017-05-16 15:22:04 -06:00
from markdown import markdown
2017-03-02 10:54:27 -07:00
from os import path
2015-05-09 02:38:39 -06:00
from shortuuidfield import ShortUUIDField
2017-03-02 10:54:27 -07:00
from uuid import uuid4
2015-05-09 02:38:39 -06:00
2017-03-02 10:54:27 -07:00
from django.core.validators import MaxValueValidator, MinValueValidator
2015-04-22 05:05:30 -06:00
from django.db import models
2017-03-14 13:21:17 -06:00
from django.db.models.signals import post_save
2015-04-25 10:47:22 -06:00
from django.contrib.auth.models import User
from django.conf import settings
2015-04-22 05:05:30 -06:00
2017-03-02 10:54:27 -07:00
from db.base.helpers import gridsquare
DATA_SOURCES = ['manual', 'network', 'sids']
2017-04-07 07:18:25 -06:00
SATELLITE_STATUS = ['alive', 'dead', 're-entered']
2017-03-02 10:54:27 -07:00
def _name_payload_frame(instance, filename):
folder = 'payload_frames'
ext = 'raw'
filename = '{0}_{1}.{2}'.format(filename, uuid4().hex, ext)
return path.join(folder, filename)
2015-08-11 03:50:12 -06:00
2017-03-14 13:21:17 -06:00
def _gen_observer(sender, instance, created, **kwargs):
post_save.disconnect(_gen_observer, sender=DemodData)
try:
qth = gridsquare(instance.lat, instance.lng)
except:
instance.observer = 'Unknown'
else:
instance.observer = '{0}-{1}'.format(instance.station, qth)
instance.save()
post_save.connect(_gen_observer, sender=DemodData)
2015-07-23 06:48:58 -06:00
class TransmitterApprovedManager(models.Manager):
def get_queryset(self):
2015-07-23 06:48:58 -06:00
return super(TransmitterApprovedManager, self).get_queryset().filter(approved=True)
2015-07-07 06:09:34 -06:00
class SuggestionApprovedManager(models.Manager):
def get_queryset(self):
return super(SuggestionApprovedManager, self).get_queryset().filter(approved=False)
2015-08-13 06:36:02 -06:00
class Mode(models.Model):
name = models.CharField(max_length=10, unique=True)
def __unicode__(self):
return self.name
2015-04-22 05:05:30 -06:00
class Satellite(models.Model):
2017-03-02 10:54:27 -07:00
"""Model for all the satellites."""
2015-04-22 05:05:30 -06:00
norad_cat_id = models.PositiveIntegerField()
name = models.CharField(max_length=45)
names = models.TextField(blank=True)
2017-05-16 15:22:04 -06:00
description = models.TextField(blank=True)
image = models.ImageField(upload_to='satellites', blank=True,
help_text='Ideally: 250x250')
2017-03-25 08:43:02 -06:00
tle1 = models.CharField(max_length=200, blank=True)
tle2 = models.CharField(max_length=200, blank=True)
2017-04-07 07:18:25 -06:00
status = models.CharField(choices=zip(SATELLITE_STATUS, SATELLITE_STATUS),
max_length=10, default='alive')
2015-04-22 05:05:30 -06:00
2015-08-11 03:50:12 -06:00
class Meta:
2017-03-02 10:54:27 -07:00
ordering = ['norad_cat_id']
2015-08-11 03:50:12 -06:00
2017-05-16 15:22:04 -06:00
def get_description(self):
return markdown(self.description)
def get_image(self):
if self.image and hasattr(self.image, 'url'):
return self.image.url
else:
return settings.SATELLITE_DEFAULT_IMAGE
@property
def pending_suggestions(self):
pending = Suggestion.objects.filter(satellite=self.id).count()
return pending
@property
def has_telemetry_data(self):
2017-03-02 10:54:27 -07:00
has_data = DemodData.objects.filter(satellite=self.id).count()
return has_data
@property
def has_telemetry_decoders(self):
has_decoders = Telemetry.objects.filter(satellite=self.id).exclude(decoder='').count()
return has_decoders
2015-04-22 05:05:30 -06:00
def __unicode__(self):
2015-04-25 10:47:22 -06:00
return '{0} - {1}'.format(self.norad_cat_id, self.name)
2015-04-22 05:05:30 -06:00
2015-07-23 06:48:58 -06:00
class Transmitter(models.Model):
2017-03-02 10:54:27 -07:00
"""Model for satellite transmitters."""
2015-05-09 02:38:39 -06:00
uuid = ShortUUIDField(db_index=True, unique=True)
2015-04-22 05:05:30 -06:00
description = models.TextField()
alive = models.BooleanField(default=True)
uplink_low = models.PositiveIntegerField(blank=True, null=True)
uplink_high = models.PositiveIntegerField(blank=True, null=True)
downlink_low = models.PositiveIntegerField(blank=True, null=True)
downlink_high = models.PositiveIntegerField(blank=True, null=True)
2015-08-26 04:57:50 -06:00
mode = models.ForeignKey(Mode, blank=True, null=True,
on_delete=models.SET_NULL, related_name='transmitters')
2015-04-22 05:05:30 -06:00
invert = models.BooleanField(default=False)
2015-07-21 12:26:08 -06:00
baud = models.FloatField(validators=[MinValueValidator(0)], blank=True, null=True)
2015-07-23 06:48:58 -06:00
satellite = models.ForeignKey(Satellite, related_name='transmitters',
2015-04-22 05:05:30 -06:00
null=True)
approved = models.BooleanField(default=False)
2015-07-23 06:48:58 -06:00
objects = TransmitterApprovedManager()
2015-04-22 05:05:30 -06:00
def __unicode__(self):
return self.description
2015-04-25 10:47:22 -06:00
def update_from_suggestion(self, suggestion):
self.description = suggestion.description
self.alive = suggestion.alive
self.downlink_low = suggestion.downlink_low
self.downlink_high = suggestion.downlink_high
self.uplink_low = suggestion.uplink_low
self.uplink_high = suggestion.uplink_high
self.mode = suggestion.mode
self.invert = suggestion.invert
self.baud = suggestion.baud
self.approved = True
self.save()
2015-04-25 10:47:22 -06:00
2015-07-23 06:48:58 -06:00
class Suggestion(Transmitter):
2017-03-02 10:54:27 -07:00
"""Model for transmitter suggestions."""
2015-04-26 08:30:33 -06:00
citation = models.CharField(max_length=255, blank=True)
user = models.ForeignKey(User, blank=True, null=True,
on_delete=models.SET_NULL)
2015-07-23 06:48:58 -06:00
transmitter = models.ForeignKey(Transmitter, blank=True, null=True,
on_delete=models.SET_NULL, related_name='suggestions')
2015-07-07 06:09:34 -06:00
objects = SuggestionApprovedManager()
def __unicode__(self):
return self.description
2016-05-06 11:20:09 -06:00
2017-03-02 10:54:27 -07:00
class Telemetry(models.Model):
"""Model for satellite telemtry decoders."""
satellite = models.ForeignKey(Satellite, null=True, related_name='telemetries')
name = models.CharField(max_length=45)
schema = models.TextField(blank=True)
decoder = models.CharField(max_length=20, blank=True)
class Meta:
ordering = ['satellite__norad_cat_id']
verbose_name_plural = 'Telemetries'
def __unicode__(self):
return self.name
2016-05-06 11:20:09 -06:00
class DemodData(models.Model):
2017-03-02 10:54:27 -07:00
"""Model for satellite for observation data."""
satellite = models.ForeignKey(Satellite, null=True, related_name='telemetry_data')
transmitter = models.ForeignKey(Transmitter, null=True, blank=True)
source = models.CharField(choices=zip(DATA_SOURCES, DATA_SOURCES),
max_length=7, default='sids')
data_id = models.PositiveIntegerField(blank=True, null=True)
payload_frame = models.FileField(upload_to=_name_payload_frame, blank=True, null=True)
payload_decoded = models.TextField(blank=True)
payload_telemetry = models.ForeignKey(Telemetry, null=True, blank=True)
station = models.CharField(max_length=45, default='Unknown')
2017-03-14 13:21:17 -06:00
observer = models.CharField(max_length=60, blank=True)
2017-03-02 10:54:27 -07:00
lat = models.FloatField(validators=[MaxValueValidator(90), MinValueValidator(-90)],
default=0)
lng = models.FloatField(validators=[MaxValueValidator(180), MinValueValidator(-180)],
default=0)
timestamp = models.DateTimeField(null=True)
class Meta:
ordering = ['-timestamp']
def __unicode__(self):
return 'data-for-{0}'.format(self.satellite.norad_cat_id)
2017-03-14 13:21:17 -06:00
def display_decoded(self):
try:
json.dumps(self.payload_decoded)
except:
'{}'
def display_frame(self):
with open(self.payload_frame.path) as fp:
return fp.read()
2017-03-21 10:23:30 -06:00
2017-03-14 13:21:17 -06:00
post_save.connect(_gen_observer, sender=DemodData)