Наземные станции¶
Станция (Station) — точка приёма в сети. Принадлежит пользователю, имеет координаты,
набор антенн и настройки планирования.
Статусы¶
Состояние станции не хранится: оно выводится из трёх величин — last_seen,
is_available и testing — каждый раз, когда его спрашивают, и потому не может
разъехаться с сердцебиением. Station.status_badge возвращает слаг состояния,
Station.status_label — его название.
Слаг |
Значение |
Условие |
|---|---|---|
|
На связи и открыта сети |
|
|
Работает, наблюдения считаются тестовыми |
то же плюс |
|
На связи, но владелец закрыл приём |
то же плюс |
|
Не выходила на связь дольше сердцебиения |
|
|
Ни разу не выходила на связь |
|
unavailable — состояние, которым владелец закрывает станцию для чужих наблюдений,
оставаясь на связи: свои наблюдения он планирует как обычно, собственное расписание
станции продолжает работать, сетевое автопланирование её не трогает. Флажок — в
настройках станции.
Переходы пишутся в StationStatusLog (три булевых: is_connected, is_available,
testing). Строка появляется при сохранении станции, если состояние действительно
изменилось; уход станции со связи никто не сохраняет, поэтому его раз в час
дописывает задача station_log_disconnect.
В API v1 (/api/stations/) поле status по-прежнему отдаёт три слова
Online/Testing/Offline, и unavailable в них читается как Offline — станция,
которая никогда не обновится, продолжает видеть тот же словарь. Фильтр
?status=2|1|0 работает по тем же правилам.
Основные поля¶
Поле |
Назначение |
|---|---|
|
Владелец, |
|
Отображаемое имя |
|
Широта (−90…90), долгота (−180…180), высота над уровнем моря в метрах (от −500: станция ниже уровня моря — реальный случай) |
|
QTH-локатор. Не колонка: считается из координат тем же |
|
Минимальный угол места в градусах, ниже которого наблюдения не планируются |
|
Целевой коэффициент загрузки станции, 0…100 |
|
Версия и идентификатор клиента |
|
Что станция сообщила о себе через |
|
Конфигурация, сохранённая владельцем в форме «Настройки станции»: плоский словарь с именами переменных окружения клиента, номер сохранения, время. |
|
Разовые просьбы к станции из формы настроек — |
|
Канал релизов ( |
|
Кому разрешено планировать спутники-нарушители: «Никто» (0), «Только операторы» (1), «Все» (2) |
|
Дата вывода станции в подборку |
Конфигурация с портала¶
Владелец настраивает приёмник, усиление, поправки частоты, поворотное устройство,
запись IQ и уровни логов в форме «Настройки станции» (stations/edit/<id>/) — той же,
где имя, координаты и антенны, с пояснением у каждого поля. Кнопку «Настройки
станции» на странице станции видят владелец, модераторы и суперпользователи.
Единый список полей — STATION_CONFIG_FIELDS в
network/base/station_config.py; ключи совпадают с переменными окружения клиента
и с его MANAGED_FIELDS. Сохранение, которое меняет поле конфигурации, — новое
поколение: станция забирает документ GET /api/v2/stations/<id>/state/ (и получает
его по MQTT сразу), открывает приёмник с новыми параметрами и применяет между
проходами; итог возвращается в reported_status.config и показывается на странице
как «поколение N применено» или «отклонено: …». Сохранение без правок конфигурации —
имя, координаты, антенны — поколения не создаёт. Пока владелец ничего не сохранил,
форма предзаполняется фактическими значениями со станции, и станция остаётся на своём
.env, пока в конфигурации что-нибудь не изменят; кнопка «Заполнить с станции»
подставляет эти значения и позже. Что станция делает с документом —
docs/station/configuration.md клиента.
Там же — то, что станция узнала о себе сама. Блок «Найденные приёмники» показывает
устройства SoapySDR, которые станция перечислила (на старте, раз в час в простое и по
кнопке «Пересканировать»), с входами, диапазоном усиления и частотами дискретизации;
«Использовать» подставляет их в поля формы. Блок «Калибровка усиления» по кнопке
просит станцию прогнать свип по усилению на частотах антенн (середины диапазонов,
можно править) и рисует шумовую полку графиком; «Применить рекомендованное» ставит
усиление, на котором полка поднялась на порог станции. Обе кнопки — команды в
Station.commands, часть документа state/.
Блок «Качество приёма» показывает и поправку опорного генератора
(network/base/ppm_estimate.py): клиент на каждом проходе измеряет по водопаду
остаток смещения несущей после доплера (signal.ppm_error) и сообщает, с какой
поправкой проход шёл (reception.ppm); поправка, которая гасит остаток, —
reception.ppm − ppm_error (знак сверен по проду 2026-10-09). Портал берёт
последние 100 проходов с кадрами и SNR ≥ 10 дБ, считает медиану по проходам
каждого спутника, а итог — медиану по спутникам: уплывший спутник остаётся
выбросом. Оценка уверенная от 10 проходов и 3 спутников при разбросе до 1 ppm;
тогда кнопка «Применить» подставляет её в поле «Поправка опорного генератора»,
сохранение — обычное новое поколение. Смена приёмника (reception.sdr)
начинает отсчёт заново. Флажок «Автоподстройка ppm» в группе «Частота и
коррекции» — переключатель портала, не станции (поколения не создаёт): ночная
задача auto_tune_frequency_corrections (03:30) у таких станций при уверенной
оценке и отличии от текущей ≥ 0,5 ppm сама записывает поправку в
desired_config новым поколением и публикует документ.
Та же задача правит дрейф передатчика (Transmitter.downlink_drift, ppb):
смещение, которое после вычета вклада станции повторяется у одного передатчика
на разных станциях, принадлежит спутнику. В расчёт идут только станции с
уверенной оценкой ppm (независимо от флажка), проходы за 60 дней, только
одночастотные передатчики типа Transmitter; медиана по станциям, уверенность —
от 3 станций и 15 проходов при разбросе до 500 ppb, порог правки — 300 Гц.
Пока AUTO_TRANSMITTER_DRIFT в .env выключен (по умолчанию), задача только
пишет в лог «would set transmitter … ppb»; включённая — записывает дрейф
(save(), так что будущие наблюдения получают новый снимок) и строку в
TransmitterDriftLog, видимую в админке вместе со сдвигом в герцах. У
передатчика в админке рядом с полем дрейфа показан его перевод в герцы и курс
«1 кГц = N ppb» на его частоте.
Антенны и диапазоны¶
Антенна (Antenna) ссылается на тип (AntennaType) и содержит один или несколько
диапазонов (FrequencyRange). Ограничения:
MAX_ANTENNAS_PER_STATION— антенн на станцию (по умолчанию 4);MAX_FREQUENCY_RANGES_PER_ANTENNA— диапазонов на антенну;MIN_FREQUENCY_FOR_RANGE/MAX_FREQUENCY_FOR_RANGE— допустимые границы.
Диапазон автоматически классифицируется по радиодиапазонам (VHF/UHF/L/S) — границы
задаются переменными VHF_MIN_FREQUENCY, VHF_MAX_FREQUENCY, UHF_*, L_*, S_*
(см. Конфигурация). Планирование сопоставляет диапазоны антенн с частотами
передатчиков спутника.
Список поддерживаемых типов антенн загружается начальными фикстурами
(django-admin initialize) и переведён на русский в интерфейсе: диполь, V-дипольная,
дисконная, базовая, яги, кросс-яги, спиральная, параболическая, вертикальная,
турникетная, квадрифилярная, «взбивалка», линденблад, паразитная линденблад и др.
Регистрация станции¶
Клиент регистрируется через POST /api/station/register. Дальше он забирает свои
задания из /api/jobs/ и отправляет результаты в /api/observations/ и
/api/demoddata/ — см. Обзор эндпоинтов.
Проверить состояние станции можно через GET /api/stations/check.
Настройки автопланирования¶
У станции может быть до двух расписаний и одно общесетевое:
Модель |
Связь |
Назначение |
|---|---|---|
|
one-to-one со станцией |
Основное расписание станции |
|
one-to-one со станцией |
Дополнительное расписание |
|
одиночная запись |
Общесетевое расписание |
У всех трёх одинаковая структура: флаг active, список спутников (satellites, JSON)
и параметры (param, JSON) — минимальный угол места, азимутальные окна и прочие
ограничения. Как эти параметры применяются, описано в Планирование наблюдений.
Статистика¶
StationStat хранит агрегаты по станции. Пересчитываются задачами
calculate_all_station_stat / calculate_station_stat (ежедневно в 03:00 UTC).
Суточные метрики по станциям ведёт отдельное приложение — см. Аналитика.
Уведомления о проблемах¶
Задача notify_for_stations_without_results находит станции, у которых подряд идут
наблюдения без результатов (порог — OBS_NO_RESULTS_MIN_COUNT, по умолчанию 3), и
отправляет уведомление на EMAIL_FOR_STATIONS_ISSUES. Период проверки —
OBS_NO_RESULTS_CHECK_PERIOD.