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

225 lines
7.2 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
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
)
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)
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
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()
@property
def has_data(self):
return self.data_set.exclude(payload='').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)
@property
def is_past(self):
return self.end < now()
class Meta:
ordering = ['-start', '-end']