Орбитальные данные (TLE)

Наборы TLE — основа всех расчётов пролётов. Портал собирает их из нескольких источников, выбирает победителя по приоритету и отдаёт наружу через API.

Модели

Tle

Одна запись на «источник × загрузка». Источник хранится в tle_source.

LatestTleSet

Указатель на текущий выбранный набор для спутника (latest).

То есть история загрузок сохраняется целиком, а LatestTleSet — это результат отбора.

Источники

Источник

Откуда

Manual

Заведён вручную через админку

SpaceTrack

Каталог Space-Track (SPACE_TRACK_GP_QUERY_URL)

Celestrak

CelesTrak, группа active

Celestrak SupGP

Предстартовый файл SupGP запуска, см. Запуски

SatNOGS

https://db.satnogs.org/api/tle/?format=3le

Список источников задан кодом: три блока внутри fetch_tle, по одному на Space-Track, CelesTrak и SatNOGS DB. Настройки, добавляющей источник снаружи, нет — новый источник заводится отдельным блоком в задаче.

Загрузка идёт задачей fetch_tle каждые 4 часа. Celestrak SupGP стоит особняком: его пишет своя задача fetch_launch_supgp, и только аппаратам запусков, у которых назван файл.

Клиент Space-Track

network/base/spacetrack_client.py — минимальный клиент для массовой загрузки элементов. Space-Track требует логина перед любым запросом и жёстко ограничивает число сессий и запросов на аккаунт, поэтому клиент логинится один раз за вызов и делает один массовый запрос активного каталога вместо запроса на спутник. Одна загрузка раз в 4 часа укладывается в лимиты.

Важно

Стенд и прод используют разные учётки Space-Track — они подставляются при деплое из CI/CD-переменных (SPACE_TRACK_USERNAME_DEV/_PROD), а не лежат в env-dist на сервере. Общий аккаунт на два контура выбирает лимит вдвое быстрее.

Выбор победителя

network/base/tle_priority.py решает, какой из наборов станет LatestTleSet.latest.

Фиксированный приоритет источников:

Manual > SpaceTrack > Celestrak > Celestrak SupGP > SatNOGS

Предстартовый вектор состояния лучше пересказа его же из SatNOGS и хуже каталога: как только у аппарата появляется настоящий номер, SpaceTrack и Celestrak его вытесняют.

Приоритет ограничен окном свежести: источник с более высоким приоритетом выигрывает, только если его данные не старше TLE_PRIORITY_FRESHNESS_DAYS (по умолчанию 7 дней). Если ни один приоритетный источник не свеж, побеждает просто самый недавно обновлённый набор — независимо от источника. Из двух наборов одного источника с одной эпохой побеждает записанный позже: источник, исправивший элементы без сдвига эпохи, иначе не был бы услышан.

Имена аппаратов

Имя спутника обогащается независимо от выбора орбитальных параметров. Заглушки вида OBJECT S (Space-Track) или TRANSPORTER-15 OBJECT L (CelesTrak) распознаются по шаблону и заменяются первым осмысленным именем, найденным при обходе источников в том же порядке приоритета.

Публичная выдача

GET /api/latesttles/ отдаёт актуальные наборы. Особенности:

  • Доступен без авторизации, лимит — LATEST_TLES_THROTTLE_RATE (60 запросов в минуту).

  • Форматы: ?FORMAT=tle и ?FORMAT=json.

  • Отдаются только аппараты на орбите. Поскольку Satellite.status проставляется руками, основным признаком служит возраст TLE: сошедший с орбиты объект выпадает из выборки Space-Track (decay_date/null-val) и перестаёт обновляться. Порог — LATEST_TLES_MAX_AGE_DAYS (30 дней), его можно поднять, если источник временно сломан.

Полная история — GET /api/tles/.

Экспорт наборов наружу выполняет задача export_tle.

Публикация TLE

POST /api/tles/ принимает наборы извне — для внешних сервисов определения орбиты, которые считают элементы по результатам наблюдений и возвращают результат в каталог. Без этого эндпоинта такая запись возможна только через админку.

Опубликованный набор сохраняется с источником Manual — первым в списке приоритета. Это сделано осознанно: проверенный вручную, посчитанный извне набор и есть ручной ввод, а Manual уже стоит первым, так что новый свежий набор выигрывает select_latest_tle и начинает определять планирование всей сети. Клиент не может выбрать значение источника сам.

Из этого следуют два ограничения:

  • право публикации проверяется точечно, по конкретному спутнику (publish_tle_perms);

  • набор проходит те же проверки, что и форма в админке (validate_tle): контрольные суммы, совпадение номеров объекта в обеих строках, диапазоны элементов, положительные перигей и апогей.

После сохранения сразу пересчитывается LatestTleSet для этого спутника. Ответ — 201 с идентификатором созданной записи.

Аутентификация здесь шире, чем в остальном API: помимо токена и сессии принимается Bearer-токен через OIDC, чтобы сервис мог действовать от имени пользователя, инициировавшего публикацию. Общепроектные классы аутентификации при этом не меняются.

Спутник выбирается по sat_id, если он передан, иначе по norad_cat_id. Номер каталога не уникален в схеме, поэтому при поиске по номеру из нескольких совпадений выбирается детерминированно первый по id. Клиенту, который знает спутник, следует передавать sat_id. norad_cat_id обязателен в любом случае: это номер в строках набора. Если спутник не найден, ответ 404.

Так публикует, например, суточный расчёт TLE по ГНСС-маякам спутника gscn: отдельный репозиторий soniks-tle-from-gnss с запуском по расписанию GitLab, не функция сети.

Пересчёт запланированных наблюдений

Появление свежего TLE не переписывает уже созданные наблюдения само по себе — этим занимается update_future_observations_with_new_tle_sets (каждые 30 минут), пересчитывая окна будущих наблюдений. См. Планирование наблюдений.

Тесты

Логика отбора и разбора покрыта отдельно: network/base/test_tle_priority.py, network/base/test_tle_utils.py, network/base/test_tle_admin_form.py, network/base/test_spacetrack_client.py.