# FR24 Noisemap — Полное описание системы > Актуально на: 2026-04-26 ## Назначение проекта Система сбора, хранения и визуализации данных о воздушном движении над московскими аэропортами (SVO, DME, VKO, ZIA) для построения **карты шумового загрязнения** от авиации. --- ## Инфраструктура **VM:** `fr24@192.168.2.67` (VM-FR24 в домашней сети, доступ через jump-host vpn-srv) **Доступ:** `ssh -i ha_ssh_key -J vpn@185.130.212.192:3322 fr24@192.168.2.67` **Docker Compose:** `/home/fr24/projects/fr24/compose/docker-compose.yml` --- ## Контейнеры (10 шт.) ### Слой хранения | Контейнер | Порт | Назначение | |---|---|---| | `fr24-postgres` | 5432 | PostgreSQL 15 + PostGIS. Единая БД `fr24` со схемами: `fr24`, `fr24_ext`, `fr24_mart` | | `fr24-backup` | — | Ежедневный pg_dump в `/backup/` | ### Слой сбора RTL-SDR | Контейнер | Порт | Назначение | |---|---|---| | `fr24-capture` | — | Читает ADS-B поток с dump1090 (SBS port 30003). Пишет сырые пакеты в `fr24.raw_packets`. Retention 3 дня. | | `fr24-preprocess` | — | Читает `fr24.raw_packets`, строит нормализованные `fr24.flights`, `fr24.tracks`, `fr24.track_points`. Поддерживает recovery после сбоя. **M4-фильтр выбросов координат** (26.04.2026). | ### Слой внешних треков | Контейнер | Порт | Назначение | |---|---|---| | `fr24-tracks-fr24` | 8001 | Загрузка треков из FR24 API (AeroAPI). `POST /run?date=YYYY-MM-DD` — вручную. Пишет в `fr24_ext.flight_tracks_fr24` + `fr24_ext.track_points_fr24`. Стоимость: ~40 кредитов/рейс. | | `fr24-tracks-fa` | 8002 | Загрузка треков из FlightAware AeroAPI. `POST /run?date=YYYY-MM-DD` — вручную. Пишет в `fr24_ext.flight_tracks_fa` + `fr24_ext.track_points_fa`. Стоимость: $0.01/запрос. | ### Слой расписания и витрины | Контейнер | Порт | Назначение | |---|---|---| | `fr24-schedule` | 8000 | Загрузка расписания из Яндекс Расписаний API. Запускается по cron T-1. Пишет в `fr24_ext.schedule`. Rate limit: ~100 запросов/час. | | `fr24-mart` | 8003 | ETL-витрина. Объединяет расписание + треки из всех источников. Запускается по расписанию каждый час (T-1) и вручную `POST /run?date=YYYY-MM-DD`. Пишет в `fr24_mart.*`. | ### Слой отдачи данных и мониторинга | Контейнер | Порт | Назначение | |---|---|---| | `fr24-api` | 8080 | REST API для фронтенда. Читает из `fr24`, `fr24_ext`, `fr24_mart`. Эндпоинты: расписание, мониторинг, data-sources. | | `fr24-monitoring` | — | Мониторинг системы. Раз в минуту логирует: disk%, db_size, capture_lag, throughput, unprocessed. Алерты при деградации. | --- ## Схема базы данных ### Схема `fr24` — RTL-SDR данные (real-time) ``` fr24.raw_packets — сырые SBS-пакеты от dump1090 fr24.aircraft — реестр воздушных судов (icao24, callsign, reg) fr24.flights — рейсы (callsign, started_at, ended_at) fr24.tracks — треки рейсов fr24.track_points — точки трека (lat, lon, altitude_m, speed, heading) fr24.processing_state — курсор обработки (для recovery) fr24.noise_results — результаты расчёта шума (устаревшее, мигрировано в mart) ``` ### Схема `fr24_ext` — внешние источники ``` fr24_ext.schedule — расписание (Яндекс). ~1400 рейсов/день на 4 аэропорта. Ключевые поля: schedule_id, flight_date, airport_iata, direction, flight_number, origin_iata, destination_iata, scheduled_at, thread_title (маршрут из Яндекса) fr24_ext.flight_tracks_fr24 — заголовки треков FR24 API fr24_ext.track_points_fr24 — точки треков FR24 (altitude_ft, gspeed_kt) fr24_ext.flight_tracks_fa — заголовки треков FlightAware fr24_ext.track_points_fa — точки треков FA (altitude_ft, gspeed_kt) fr24_ext.load_state — состояние загрузок (для идемпотентности) ``` ### Схема `fr24_mart` — финальная витрина ``` fr24_mart.flights — объединённые рейсы. Один рейс = одна строка. Флаги: has_rtlsdr, has_fr24, has_fa track_source: 'rtlsdr' | 'fr24' | 'fa' | null Ссылки: fr24_track_id, fa_track_id, rtlsdr_flight_id fr24_mart.track_points — точки трека с noise_score (расчёт по шумовой модели) fr24_mart.noise_grid — агрегат по ячейкам 0.01°×0.01° (~1 км). AVG(noise_score) fr24_mart.source_coverage — покрытие по источникам (% рейсов с треком) ``` --- ## ETL-процессы ### 1. RTL-SDR pipeline (real-time) ``` РТЛ-SDR RTL2838 (USB, 1090 МГц) → dump1090-fa (SBS-1 декодер) → TCP :30003 → fr24-capture → fr24.captures + fr24.raw_packets (base64, partitioned/date) → fr24-preprocess → fr24.aircraft + fr24.flights + fr24.tracks + fr24.track_points ``` **Алгоритм preprocess:** - MSG1 = callsign, MSG3 = позиция (lat/lon/alt), MSG4 = скорость/курс (кешируется 30 сек, обогащает MSG3) - gap > 30 мин без точек → закрыть рейс, создать новый - `onground=1` → точку пропустить - **M4-фильтр (26.04.2026):** скорость между точками > 350 м/с (Mach 1) → выброс, точка не записывается **Антенна:** - Местоположение: д. Хоругвино, Солнечногорский р-н, МО - Координаты: 56.121°N, 37.216°E - Оборудование: RTL-SDR RTL2838 DVB-T - **Покрытие:** ~230 рейсов/день (~9.6% от расписания) - **Задержка:** 1-2 сек - **Throughput:** ~3000 пакетов/5 мин ### 2. Schedule pipeline (ежедневно T-1) ``` Яндекс Расписания API → fr24-schedule → fr24_ext.schedule ``` - **4 аэропорта × 2 направления** = ~1400 рейсов/день - **Rate limit:** ~100 запросов/час → ~30 запросов на один день - **thread_title:** парсится из `thread.title` (маршрут "Москва → Санкт-Петербург") ### 3. FR24 tracks pipeline (по запросу) ``` FR24 AeroAPI → fr24-tracks-fr24 → fr24_ext.flight_tracks_fr24 + track_points_fr24 ``` - Запуск: `POST http://fr24-tracks-fr24:8001/run?date=YYYY-MM-DD` - **Лимит:** Explorer тариф, остаток ~50K кредитов (40 кредитов/рейс = ~1250 рейсов) - **Хранится только по явной команде** (дорого) ### 4. FlightAware pipeline (по запросу) ``` FlightAware AeroAPI → fr24-tracks-fa → fr24_ext.flight_tracks_fa + track_points_fa ``` - Запуск: `POST http://fr24-tracks-fa:8002/run?date=YYYY-MM-DD` - **Стоимость:** $0.01/запрос, ~$28/день при полной загрузке - Rate limit: 429 после ~5-10 быстрых запросов, Retry-After 60с ### 5. Mart builder (каждый час автоматически, T-1) ``` fr24_ext.schedule + fr24.flights + fr24_ext.flight_tracks_fr24 + fr24_ext.flight_tracks_fa → build_mart.py → fr24_mart.flights + track_points + noise_grid + source_coverage ``` **Логика мэтчинга (приоритет RTL-SDR > FR24 > FA):** 1. **RTL-SDR:** `flight_number` (IATA `'SU 1057'`) → конвертируется в ICAO callsign (`'AFL1057'`) → поиск в `fr24.flights.callsign` 2. **FR24:** числовой номер рейса (`6807`) + маршрут (ICAO аэропортов → IATA через словарь) → поиск в `fr24_ext.flight_tracks_fr24` 3. **FA:** числовой номер рейса + маршрут → поиск в `fr24_ext.flight_tracks_fa` **Проблема мэтчинга (⚠️ в работе):** - RTL-SDR: требует словарь `AIRLINE_IATA_TO_ICAO` (AFL=SU, SDM=FV и т.д.) - FA: хранит ICAO ident (`CSN342`), расписание IATA (`CZ 342`) → числовой матч - Словарь аэропортов `ICAO_TO_IATA` неполный (~40 аэропортов) ### 6. Шумовая модель ``` track_points → altitude_to_noise_db(alt_ft, aircraft_type) → noise_score → AGG по ячейкам 0.01° → noise_grid ``` **Зоны:** - 0-2 км: Критический (>75 dB) - 2-5 км: Высокий (65-75 dB) - 5-7 км: Средний (55-65 dB) - 7-9 км: Низкий (45-55 dB) - >9 км: Фоновый (<45 dB) --- ## UI (фронтенд) Фронтенд: Flask + Leaflet.js, доступен через nginx reverse proxy. ### Страницы #### `/` — Карта шумового загрязнения - **Тепловая карта** (Leaflet heatmap layer) по данным `fr24_mart.noise_grid` - **Аэропорты** SVO/DME/VKO/ZIA маркерами - **Зоны влияния** 2/5/7/9 км (цветные круги) - **Выбор даты** — слайдер или датепикер - **Легенда** шума #### `/schedule` — Расписание рейсов - Таблица рейсов из `fr24_mart.flights` с маршрутами - **Фильтры:** аэропорт, направление, дата - Маршрут отображается из `thread_title` (Яндекс) — "Москва → Санкт-Петербург" - **CSV экспорт** — выгрузка с городами вместо IATA-кодов - Иконки источника трека (RTL/FR24/FA) - **Тип ВС:** `COALESCE(mf.aircraft_type, s.aircraft_type)` — сначала из витрины `fr24_mart.flights` (если есть трек), иначе из расписания `fr24_ext.schedule`. Гарантирует заполненность колонки даже для дней без RTL-SDR данных. #### `/monitoring` — Мониторинг системы - Capture lag, throughput, unprocessed packets - DB size, disk usage - Статус контейнеров - График активности за последние 24ч #### `/data-sources` — Покрытие источниками - Статистика по `fr24_mart.source_coverage` - % рейсов с треком по каждому источнику - Топ авиакомпаний, топ маршрутов - Загрузка аэропортов ### API эндпоинты (fr24-api :8080) ``` GET /api/schedule/data?date_from=&date_to=&airport=&direction= GET /api/monitoring GET /api/data-sources/coverage GET /api/data-sources/quality GET /api/data-sources/top-airlines GET /api/data-sources/top-routes GET /api/data-sources/airport-load ``` --- ## Текущий статус данных (на 26.04.2026) | Что | Количество | |---|---| | Расписание в fr24_ext | 01.04 – 19.04.2026 (~26K рейсов) | | FR24 треки | 1 рейс (FV6807, тест) | | FA треки | 5 рейсов (CSN, тест) | | RTL-SDR треки (ЗУП 35 км) | 879 треков, 74,747 точек, avg TQS=0.982 | | RTL-SDR: dump1090 | ⚠️ нестабилен (rc=1 цикл), возможна проблема USB/прав | | Витрина fr24_mart | 01.04 только (1399 рейсов, 1 с треком) | | Noise grid | 688 ячеек за 01.04 | --- ## Метрики качества ADS-B захвата Детали: `analysis/ZUP_DEFINITION.md`, SQL: `analysis/adsb_quality_metrics.sql` **Зона уверенного приёма (ЗУП):** радиус **35 км** от антенны. | Метрика | Описание | Значение в ЗУП | |---|---|---| | M1 — шаг между точками | Медианное расстояние между последовательными точками трека | 26 м | | M2 — временной интервал | Медианный dt между точками; gap rate (gap>30 сек) | 0.8 сек; 2.2% | | M3 — точек на трек | Кол-во точек трека в ЗУП | медиана ~85, всего 74,747 | | M4 — выбросы координат | Доля точек со скоростью > 350 м/с | отфильтровано (пересчёт 26.04.2026) | | TQS | Track Quality Score (0..1) | 0.982 среднее (после пересчёта 26.04.2026) | **M4-фильтр** добавлен в `fr24-preprocess` 26.04.2026 — выбросы отсекаются до записи в БД. --- ## Известные ограничения и backlog | # | Проблема | Приоритет | |---|---|---| | 1 | Мэтчинг RTL-SDR: IATA→ICAO конвертация авиакомпаний не реализована | 🔴 Высокий | | 2 | Мэтчинг FA: ICAO ident в БД vs IATA в расписании | 🔴 Высокий | | 3 | DDL: `origin_icao`/`destination_icao` VARCHAR(5) в flight_tracks_fa | 🔴 Высокий | | 4 | Словарь ICAO_TO_IATA аэропортов неполный (~40 из нужных 200+) | 🟡 Средний | | 5 | Яндекс backfill 06–19.04 не завершён (rate limit 429) | 🟡 Средний | | 6 | Витрина не содержит данных за 02–19.04 | 🟡 Средний | | 7 | Duration рейсов: только 6.6% заполнено | 🟢 Низкий | --- ## Ключи и конфиги | Сервис | Переменная | Где | |---|---|---| | FR24 API | `FR24_API_KEY` | `.env` на VM | | FlightAware | `FLIGHTAWARE_API_KEY` | `.env` на VM | | Яндекс Расписания | `YANDEX_API_KEY` | `.env` на VM | | PostgreSQL | `POSTGRES_PASSWORD=change-me` | docker-compose | FR24 Explorer: остаток **~50 486 кредитов** из 120K (промо до 31.05.2026) FlightAware: потрачено **$0.05** из pay-per-use Яндекс: **rate limit** сбросится ~23:30 UTC 21.04