Files
dbstorage/dbapp/mainapp/models/parameters.py

272 lines
9.1 KiB
Python

"""
Модели параметров сигнала (Parameter, SigmaParameter).
"""
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models import ExpressionWrapper, F
from .defaults import (
get_default_polarization,
get_default_modulation,
get_default_standard,
)
class Parameter(models.Model):
id_satellite = models.ForeignKey(
'mainapp.Satellite',
on_delete=models.PROTECT,
related_name="parameters",
verbose_name="Спутник",
null=True,
)
polarization = models.ForeignKey(
'mainapp.Polarization',
default=get_default_polarization,
on_delete=models.SET_DEFAULT,
related_name="polarizations",
null=True,
blank=True,
verbose_name="Поляризация",
)
frequency = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="Частота, МГц",
db_index=True,
help_text="Центральная частота сигнала",
)
freq_range = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="Полоса частот, МГц",
help_text="Полоса частот сигнала",
)
bod_velocity = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="Символьная скорость, БОД",
help_text="Символьная скорость должна быть положительной",
)
modulation = models.ForeignKey(
'mainapp.Modulation',
default=get_default_modulation,
on_delete=models.SET_DEFAULT,
related_name="modulations",
null=True,
blank=True,
verbose_name="Модуляция",
)
snr = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="ОСШ",
help_text="Отношение сигнал/шум",
)
standard = models.ForeignKey(
'mainapp.Standard',
default=get_default_standard,
on_delete=models.SET_DEFAULT,
related_name="standards",
null=True,
blank=True,
verbose_name="Стандарт",
)
objitem = models.OneToOneField(
'mainapp.ObjItem',
on_delete=models.CASCADE,
related_name="parameter_obj",
verbose_name="Объект",
null=True,
blank=True,
help_text="Связанный объект",
)
def clean(self):
"""Валидация на уровне модели"""
super().clean()
# Проверка что частота больше полосы частот
if self.frequency and self.freq_range:
if self.freq_range > self.frequency:
raise ValidationError(
{"freq_range": "Полоса частот не может быть больше частоты"}
)
# Проверка что символьная скорость соответствует полосе частот
if self.bod_velocity and self.freq_range:
if self.bod_velocity > self.freq_range * 1000000: # Конвертация МГц в Гц
raise ValidationError(
{
"bod_velocity": "Символьная скорость не может превышать полосу частот"
}
)
def __str__(self):
polarization_name = self.polarization.name if self.polarization else "-"
modulation_name = self.modulation.name if self.modulation else "-"
return f"Источник-{self.frequency}:{self.freq_range} МГц:{polarization_name}:{modulation_name}"
class Meta:
verbose_name = "ВЧ загрузка"
verbose_name_plural = "ВЧ загрузки"
indexes = [
models.Index(fields=["id_satellite", "frequency"]),
models.Index(fields=["frequency", "polarization"]),
]
class SigmaParameter(models.Model):
TRANSFERS = [(-1.0, "-"), (9750.0, "9750 МГц"), (10750.0, "10750 МГц")]
id_satellite = models.ForeignKey(
'mainapp.Satellite',
on_delete=models.PROTECT,
related_name="sigmapar_sat",
verbose_name="Спутник",
)
transfer = models.FloatField(
choices=TRANSFERS,
default=-1.0,
verbose_name="Перенос по частоте",
help_text="Выберите перенос по частоте",
)
status = models.CharField(
max_length=20,
blank=True,
null=True,
verbose_name="Статус",
help_text="Статус измерения",
)
frequency = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="Частота, МГц",
db_index=True,
help_text="Центральная частота сигнала",
)
transfer_frequency = models.GeneratedField(
expression=ExpressionWrapper(
F("frequency") + F("transfer"), output_field=models.FloatField()
),
output_field=models.FloatField(),
db_persist=True,
null=True,
blank=True,
verbose_name="Частота в Ku, МГц",
)
freq_range = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="Полоса частот, МГц",
help_text="Полоса частот",
)
power = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="Мощность, дБм",
help_text="Мощность сигнала",
)
bod_velocity = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="Символьная скорость, БОД",
help_text="Символьная скорость должна быть положительной",
)
polarization = models.ForeignKey(
'mainapp.Polarization',
default=get_default_polarization,
on_delete=models.SET_DEFAULT,
related_name="polarizations_sigma",
null=True,
blank=True,
verbose_name="Поляризация",
)
modulation = models.ForeignKey(
'mainapp.Modulation',
default=get_default_modulation,
on_delete=models.SET_DEFAULT,
related_name="modulations_sigma",
null=True,
blank=True,
verbose_name="Модуляция",
)
snr = models.FloatField(
default=0,
null=True,
blank=True,
verbose_name="ОСШ, Дб",
validators=[MinValueValidator(-50), MaxValueValidator(100)],
help_text="Отношение сигнал/шум в диапазоне от -50 до 100 дБ",
)
standard = models.ForeignKey(
'mainapp.Standard',
default=get_default_standard,
on_delete=models.SET_DEFAULT,
related_name="standards_sigma",
null=True,
blank=True,
verbose_name="Стандарт",
)
packets = models.BooleanField(
null=True,
blank=True,
verbose_name="Пакетность",
help_text="Наличие пакетной передачи",
)
datetime_begin = models.DateTimeField(
null=True,
blank=True,
verbose_name="Время начала измерения",
help_text="Дата и время начала измерения",
)
datetime_end = models.DateTimeField(
null=True,
blank=True,
verbose_name="Время окончания измерения",
help_text="Дата и время окончания измерения",
)
parameter = models.ForeignKey(
'mainapp.Parameter',
on_delete=models.SET_NULL,
related_name="sigma_parameter",
verbose_name="ВЧ",
null=True,
blank=True,
)
def clean(self):
"""Валидация на уровне модели"""
super().clean()
# Проверка что время окончания больше времени начала
if self.datetime_begin and self.datetime_end:
if self.datetime_end < self.datetime_begin:
raise ValidationError(
{"datetime_end": "Время окончания должно быть позже времени начала"}
)
# Проверка что частота больше полосы частот
if self.frequency and self.freq_range:
if self.freq_range > self.frequency:
raise ValidationError(
{"freq_range": "Полоса частот не может быть больше частоты"}
)
def __str__(self):
modulation_name = self.modulation.name if self.modulation else "-"
return f"Sigma-{self.frequency}:{self.freq_range} МГц:{modulation_name}"
class Meta:
verbose_name = "ВЧ sigma"
verbose_name_plural = "ВЧ sigma"