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

283 lines
9.3 KiB
Python
Raw Normal View History

2016-01-26 00:55:55 -07:00
from datetime import datetime, timedelta
from shortuuidfield import ShortUUIDField
2014-09-01 14:21:53 -06:00
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
2014-09-08 11:36:12 -06:00
from django.utils.timezone import now
2015-02-05 17:35:27 -07:00
from django.conf import settings
from django.utils.html import format_html
2014-09-01 14:21:53 -06:00
2014-12-19 06:06:58 -07:00
from network.users.models import User
from network.base.helpers import get_apikey
2014-09-01 14:21:53 -06:00
RIG_TYPES = ['Radio', 'SDR']
2014-09-01 14:21:53 -06:00
ANTENNA_BANDS = ['HF', 'VHF', 'UHF', 'L', 'S', 'C', 'X', 'KU']
ANTENNA_TYPES = (
('dipole', 'Dipole'),
('yagi', 'Yagi'),
('helical', 'Helical'),
('parabolic', 'Parabolic'),
('vertical', 'Verical'),
2014-09-01 14:21:53 -06:00
)
Initial data vetting/verification system Model change (with migration 0006) adds 3 fields to Data: vetted_status (charfield with options for data status, default "unknown") vetted_user (who vetted the data) vetted_datetime (when it was vetted) In addition, various boolean functions are added for the Data model to check statuses. More functions are added to the Observation model to check status of verification within an observation as well, assuming multiple data entries in an Observation. With these, I also changed "has_data" to "has_submitted_data" to be more specific alongside the others. For UX, we add a green check sign or red removal sign to the data header in Observation view (along with green/red datetime in the footer) if a data is verified good or bad, respectively. If there is an unknown status, the data header is given a thumbs-up and thumbs-down button to verify the data good or bad. These icons are only offered to is_staff, the observation requestor, and any station owner in the observation. These buttons trigger new URLs/functions in view: data_verify(id) data_mark_bad(id) Returning the user back to the originating Observation page. In the observation lists I changed the coloring of the ID button to be: Future: light blue (same) No uploaded data and/or all vetted bad data: red Some or all unvetted data with no verified good data: orange Some or all verified good data: green These changes are reflected in the observations.html, home.html, and user_detail.html templates. solves satnogs/satnogs-network#171
2016-03-25 13:52:45 -06:00
OBSERVATION_STATUSES = (
('unknown', 'Unknown'),
('verified', 'Verified'),
('data_not_verified', 'Has Data, Not Verified'),
('no_data', 'No Data'),
)
class Rig(models.Model):
name = models.CharField(choices=zip(RIG_TYPES, RIG_TYPES), max_length=10)
rictld_number = models.PositiveIntegerField(blank=True, null=True)
def __unicode__(self):
return '{0}: {1}'.format(self.name, self.rictld_number)
class Mode(models.Model):
name = models.CharField(max_length=10, unique=True)
def __unicode__(self):
return self.name
2014-09-01 14:21:53 -06:00
class Antenna(models.Model):
"""Model for antennas tracked with SatNOGS."""
frequency = models.FloatField(validators=[MinValueValidator(0)])
band = models.CharField(choices=zip(ANTENNA_BANDS, ANTENNA_BANDS),
max_length=5)
antenna_type = models.CharField(choices=ANTENNA_TYPES, max_length=15)
2014-12-13 11:21:05 -07:00
def __unicode__(self):
return '{0} - {1} - {2}'.format(self.band, self.antenna_type, self.frequency)
2014-12-13 11:21:05 -07:00
2014-09-01 14:21:53 -06:00
class Station(models.Model):
"""Model for SatNOGS ground stations."""
2014-10-24 11:12:58 -06:00
owner = models.ForeignKey(User)
2014-09-01 14:21:53 -06:00
name = models.CharField(max_length=45)
2015-02-05 17:35:27 -07:00
image = models.ImageField(upload_to='ground_stations', blank=True)
2014-12-03 10:58:23 -07:00
alt = models.PositiveIntegerField(help_text='In meters above ground')
2014-09-01 14:21:53 -06:00
lat = models.FloatField(validators=[MaxValueValidator(90),
MinValueValidator(-90)])
lng = models.FloatField(validators=[MaxValueValidator(180),
MinValueValidator(-180)])
qthlocator = models.CharField(max_length=255, blank=True)
location = models.CharField(max_length=255, blank=True)
antenna = models.ManyToManyField(Antenna, blank=True,
2014-12-03 10:58:23 -07:00
help_text=('If you want to add a new Antenna '
'contact SatNOGS Team'))
2014-09-17 12:30:30 -06:00
featured_date = models.DateField(null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
last_seen = models.DateTimeField(null=True, blank=True)
horizon = models.PositiveIntegerField(help_text='In degrees above 0', default=10)
uuid = models.CharField(db_index=True, max_length=100, blank=True)
rig = models.ForeignKey(Rig, blank=True, null=True, on_delete=models.SET_NULL)
2014-09-17 12:30:30 -06:00
class Meta:
ordering = ['-active', '-last_seen']
2015-02-05 17:35:27 -07:00
def get_image(self):
if self.image and hasattr(self.image, 'url'):
return self.image.url
else:
return settings.STATION_DEFAULT_IMAGE
@property
def online(self):
try:
2015-05-15 02:45:18 -06:00
heartbeat = self.last_seen + timedelta(minutes=int(settings.STATION_HEARTBEAT_TIME))
return self.active and heartbeat > now()
except:
return False
def state(self):
if self.online:
return format_html('<span style="color:green">Online</span>')
else:
return format_html('<span style="color:red">Offline</span>')
@property
def success_rate(self):
observations = self.data_set.all().count()
success = self.data_set.exclude(payload='').count()
2015-08-24 06:02:15 -06:00
if observations:
return int(100 * (float(success) / float(observations)))
else:
return False
@property
def apikey(self):
return get_apikey(user=self.owner)
def __unicode__(self):
return "%d - %s" % (self.pk, self.name)
2014-09-01 14:21:53 -06:00
class Satellite(models.Model):
"""Model for SatNOGS satellites."""
norad_cat_id = models.PositiveIntegerField()
name = models.CharField(max_length=45)
names = models.TextField(blank=True)
image = models.ImageField(upload_to='satellites', blank=True)
class Meta:
ordering = ['norad_cat_id']
def get_image(self):
if self.image and hasattr(self.image, 'url'):
return self.image.url
else:
return settings.SATELLITE_DEFAULT_IMAGE
2016-01-23 02:40:56 -07:00
@property
def latest_tle(self):
try:
latest_tle = Tle.objects.filter(satellite=self).latest('updated')
return latest_tle
except Tle.DoesNotExist:
return False
2016-01-23 02:40:56 -07:00
@property
2016-01-26 00:55:55 -07:00
def tle_no(self):
try:
line = self.latest_tle.tle1
return line[65:68]
except:
return False
2016-01-23 02:40:56 -07:00
@property
2016-01-26 00:55:55 -07:00
def tle_epoch(self):
try:
line = self.latest_tle.tle1
yd, s = line[18:32].split('.')
epoch = (datetime.strptime(yd, "%y%j") +
timedelta(seconds=float("." + s) * 24 * 60 * 60))
return epoch
except:
return False
2016-01-23 02:40:56 -07:00
def __unicode__(self):
return self.name
2016-01-22 10:48:07 -07:00
class Tle(models.Model):
tle0 = models.CharField(max_length=100, blank=True)
tle1 = models.CharField(max_length=200, blank=True)
tle2 = models.CharField(max_length=200, blank=True)
updated = models.DateTimeField(auto_now=True, blank=True)
satellite = models.ForeignKey(Satellite, related_name='tles', null=True)
class Meta:
ordering = ['tle0']
def __unicode__(self):
return self.tle0
2015-07-23 09:18:01 -06:00
class Transmitter(models.Model):
"""Model for antennas transponders."""
uuid = ShortUUIDField(db_index=True)
description = models.TextField()
2014-10-16 06:07:07 -06:00
alive = models.BooleanField(default=True)
2014-10-27 09:47:32 -06:00
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)
mode = models.ForeignKey(Mode, related_name='transmitters', blank=True,
null=True, on_delete=models.SET_NULL)
2014-10-15 09:02:47 -06:00
invert = models.BooleanField(default=False)
baud = models.FloatField(validators=[MinValueValidator(0)], null=True, blank=True)
satellite = models.ForeignKey(Satellite, related_name='transmitters', null=True)
2014-09-01 14:21:53 -06:00
def __unicode__(self):
return self.description
2014-09-01 14:21:53 -06:00
class Observation(models.Model):
"""Model for SatNOGS observations."""
2014-10-24 11:12:58 -06:00
satellite = models.ForeignKey(Satellite)
2015-07-23 09:18:01 -06:00
transmitter = models.ForeignKey(Transmitter, null=True, related_name='observations')
2016-01-22 10:48:07 -07:00
tle = models.ForeignKey(Tle, null=True)
2014-10-24 11:12:58 -06:00
author = models.ForeignKey(User)
2014-09-01 14:21:53 -06:00
start = models.DateTimeField()
end = models.DateTimeField()
class Meta:
ordering = ['-start', '-end']
2014-09-08 11:36:12 -06:00
@property
def is_past(self):
return self.end < now()
@property
def is_future(self):
return self.end > now()
@property
def is_deletable(self):
deletion = self.start - timedelta(minutes=int(settings.OBSERVATION_MAX_DELETION_RANGE))
return deletion > now()
Initial data vetting/verification system Model change (with migration 0006) adds 3 fields to Data: vetted_status (charfield with options for data status, default "unknown") vetted_user (who vetted the data) vetted_datetime (when it was vetted) In addition, various boolean functions are added for the Data model to check statuses. More functions are added to the Observation model to check status of verification within an observation as well, assuming multiple data entries in an Observation. With these, I also changed "has_data" to "has_submitted_data" to be more specific alongside the others. For UX, we add a green check sign or red removal sign to the data header in Observation view (along with green/red datetime in the footer) if a data is verified good or bad, respectively. If there is an unknown status, the data header is given a thumbs-up and thumbs-down button to verify the data good or bad. These icons are only offered to is_staff, the observation requestor, and any station owner in the observation. These buttons trigger new URLs/functions in view: data_verify(id) data_mark_bad(id) Returning the user back to the originating Observation page. In the observation lists I changed the coloring of the ID button to be: Future: light blue (same) No uploaded data and/or all vetted bad data: red Some or all unvetted data with no verified good data: orange Some or all verified good data: green These changes are reflected in the observations.html, home.html, and user_detail.html templates. solves satnogs/satnogs-network#171
2016-03-25 13:52:45 -06:00
# observation has at least 1 payload submitted, no verification taken into account
@property
Initial data vetting/verification system Model change (with migration 0006) adds 3 fields to Data: vetted_status (charfield with options for data status, default "unknown") vetted_user (who vetted the data) vetted_datetime (when it was vetted) In addition, various boolean functions are added for the Data model to check statuses. More functions are added to the Observation model to check status of verification within an observation as well, assuming multiple data entries in an Observation. With these, I also changed "has_data" to "has_submitted_data" to be more specific alongside the others. For UX, we add a green check sign or red removal sign to the data header in Observation view (along with green/red datetime in the footer) if a data is verified good or bad, respectively. If there is an unknown status, the data header is given a thumbs-up and thumbs-down button to verify the data good or bad. These icons are only offered to is_staff, the observation requestor, and any station owner in the observation. These buttons trigger new URLs/functions in view: data_verify(id) data_mark_bad(id) Returning the user back to the originating Observation page. In the observation lists I changed the coloring of the ID button to be: Future: light blue (same) No uploaded data and/or all vetted bad data: red Some or all unvetted data with no verified good data: orange Some or all verified good data: green These changes are reflected in the observations.html, home.html, and user_detail.html templates. solves satnogs/satnogs-network#171
2016-03-25 13:52:45 -06:00
def has_submitted_data(self):
return self.data_set.exclude(payload='').count()
Initial data vetting/verification system Model change (with migration 0006) adds 3 fields to Data: vetted_status (charfield with options for data status, default "unknown") vetted_user (who vetted the data) vetted_datetime (when it was vetted) In addition, various boolean functions are added for the Data model to check statuses. More functions are added to the Observation model to check status of verification within an observation as well, assuming multiple data entries in an Observation. With these, I also changed "has_data" to "has_submitted_data" to be more specific alongside the others. For UX, we add a green check sign or red removal sign to the data header in Observation view (along with green/red datetime in the footer) if a data is verified good or bad, respectively. If there is an unknown status, the data header is given a thumbs-up and thumbs-down button to verify the data good or bad. These icons are only offered to is_staff, the observation requestor, and any station owner in the observation. These buttons trigger new URLs/functions in view: data_verify(id) data_mark_bad(id) Returning the user back to the originating Observation page. In the observation lists I changed the coloring of the ID button to be: Future: light blue (same) No uploaded data and/or all vetted bad data: red Some or all unvetted data with no verified good data: orange Some or all verified good data: green These changes are reflected in the observations.html, home.html, and user_detail.html templates. solves satnogs/satnogs-network#171
2016-03-25 13:52:45 -06:00
# observaton has at least 1 payload that has been verified good
@property
def has_verified_data(self):
return self.data_set.filter(vetted_status='verified').count()
# observation is vetted to be all bad data
@property
def has_no_data(self):
return self.data_set.filter(vetted_status='no_data').count() == self.data_set.count()
Initial data vetting/verification system Model change (with migration 0006) adds 3 fields to Data: vetted_status (charfield with options for data status, default "unknown") vetted_user (who vetted the data) vetted_datetime (when it was vetted) In addition, various boolean functions are added for the Data model to check statuses. More functions are added to the Observation model to check status of verification within an observation as well, assuming multiple data entries in an Observation. With these, I also changed "has_data" to "has_submitted_data" to be more specific alongside the others. For UX, we add a green check sign or red removal sign to the data header in Observation view (along with green/red datetime in the footer) if a data is verified good or bad, respectively. If there is an unknown status, the data header is given a thumbs-up and thumbs-down button to verify the data good or bad. These icons are only offered to is_staff, the observation requestor, and any station owner in the observation. These buttons trigger new URLs/functions in view: data_verify(id) data_mark_bad(id) Returning the user back to the originating Observation page. In the observation lists I changed the coloring of the ID button to be: Future: light blue (same) No uploaded data and/or all vetted bad data: red Some or all unvetted data with no verified good data: orange Some or all verified good data: green These changes are reflected in the observations.html, home.html, and user_detail.html templates. solves satnogs/satnogs-network#171
2016-03-25 13:52:45 -06:00
# observation has at least 1 payload left unvetted
@property
def has_unvetted_data(self):
return self.data_set.filter(vetted_status='unknown').count()
def __unicode__(self):
return "%d" % self.id
2014-09-01 14:21:53 -06:00
class Data(models.Model):
2014-09-08 11:36:12 -06:00
"""Model for observation data."""
2014-09-01 14:21:53 -06:00
start = models.DateTimeField()
end = models.DateTimeField()
2014-10-24 11:12:58 -06:00
observation = models.ForeignKey(Observation)
ground_station = models.ForeignKey(Station)
2014-10-26 19:14:26 -06:00
payload = models.FileField(upload_to='data_payloads', blank=True, null=True)
payload_demode = models.FileField(upload_to='data_payloads', blank=True, null=True)
Initial data vetting/verification system Model change (with migration 0006) adds 3 fields to Data: vetted_status (charfield with options for data status, default "unknown") vetted_user (who vetted the data) vetted_datetime (when it was vetted) In addition, various boolean functions are added for the Data model to check statuses. More functions are added to the Observation model to check status of verification within an observation as well, assuming multiple data entries in an Observation. With these, I also changed "has_data" to "has_submitted_data" to be more specific alongside the others. For UX, we add a green check sign or red removal sign to the data header in Observation view (along with green/red datetime in the footer) if a data is verified good or bad, respectively. If there is an unknown status, the data header is given a thumbs-up and thumbs-down button to verify the data good or bad. These icons are only offered to is_staff, the observation requestor, and any station owner in the observation. These buttons trigger new URLs/functions in view: data_verify(id) data_mark_bad(id) Returning the user back to the originating Observation page. In the observation lists I changed the coloring of the ID button to be: Future: light blue (same) No uploaded data and/or all vetted bad data: red Some or all unvetted data with no verified good data: orange Some or all verified good data: green These changes are reflected in the observations.html, home.html, and user_detail.html templates. solves satnogs/satnogs-network#171
2016-03-25 13:52:45 -06:00
vetted_datetime = models.DateTimeField(null=True, blank=True)
vetted_user = models.ForeignKey(User, related_name="vetted_user_set", null=True, blank=True)
vetted_status = models.CharField(choices=OBSERVATION_STATUSES,
max_length=10, default='unknown')
@property
def is_past(self):
return self.end < now()
Initial data vetting/verification system Model change (with migration 0006) adds 3 fields to Data: vetted_status (charfield with options for data status, default "unknown") vetted_user (who vetted the data) vetted_datetime (when it was vetted) In addition, various boolean functions are added for the Data model to check statuses. More functions are added to the Observation model to check status of verification within an observation as well, assuming multiple data entries in an Observation. With these, I also changed "has_data" to "has_submitted_data" to be more specific alongside the others. For UX, we add a green check sign or red removal sign to the data header in Observation view (along with green/red datetime in the footer) if a data is verified good or bad, respectively. If there is an unknown status, the data header is given a thumbs-up and thumbs-down button to verify the data good or bad. These icons are only offered to is_staff, the observation requestor, and any station owner in the observation. These buttons trigger new URLs/functions in view: data_verify(id) data_mark_bad(id) Returning the user back to the originating Observation page. In the observation lists I changed the coloring of the ID button to be: Future: light blue (same) No uploaded data and/or all vetted bad data: red Some or all unvetted data with no verified good data: orange Some or all verified good data: green These changes are reflected in the observations.html, home.html, and user_detail.html templates. solves satnogs/satnogs-network#171
2016-03-25 13:52:45 -06:00
# this payload has been vetted good/bad by someone
@property
def is_vetted(self):
return not self.vetted_status == 'unknown'
# this payload has been vetted as good by someone
@property
def is_verified(self):
return self.vetted_status == 'verified'
# this payload has been vetted as bad by someone
@property
def is_no_data(self):
return self.vetted_status == 'no_data'
class Meta:
ordering = ['-start', '-end']