272 lines
9.1 KiB
Python
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"
|