Pull to refresh

VariFlight ADS-B – Flightradar по-китайски

Reading time34 min
Views30K
«Flightradar», в некотором роде, стало именем нарицательным, фактически подменяя понятие «сайт, где можно за самолетами наблюдать в реальном времени». Хотя фактически таких крупных сайтов несколько, а небольших проектов еще больше, но нередко можно увидеть в СМИ новость о авиационном событии с фразой «по данным сайта Flightradar» и скриншот с другого ресурса.

На Хабре есть ряд публикаций о радарспорттинге, в которых или в комментариях к которым упоминаются не только Flightradar. В этой публикации я расскажу о китайском сервисе по отслеживанию авиатрафика и его таком же китайском ADSB-приемнике, который они рассылают бесплатно.



Радарспоттинг достаточно интересное занятие чтобы увлечь заметное число людей. Несколько статей на Хабре неплохо описывают суть занятия:


Приемник принимает, передаваемый самолетами, сигнал на частоте 1090 МГц, дешифрует и отдает в каком-то формате. Например так:

{"updatetime":1537902225,"UTC Time":"2018-09-25 19:03:45","anum":"TCETM","fnum":"KKK6944","position":{"long":30.66455078125,"lat":39.351677},"height":10005.06,"speed":888.96,"angle":130},

Это занятие не только интересное, но стало видом деятельности нескольких компаний:


Мало кто думает чем зарабатывают на жизнь и как работают сервисы подобные Flightradar. Пример этого можно увидеть в ru.википедии "публичный веб-сервис, позволяющий в реальном времени наблюдать за положением воздушных судов, находящихся в воздухе". Сама статья и заголовок дают ложное представление о Flightradar как о неком развлекательном сервисе.

В действительности возникнув в начале 2000-х как хобби, эти компании быстро вышли на окупаемость и с каждым годом увеличивают доход. Например, компания Flightaware, основанная в 2005 году, уже в 2006 году стала прибыльной, заработав больше $1M за первые 18 месяцев, и ежегодно показывая рост 40-75%. По данным некоторых ресурсов ежегодный доход Flightaware превышает $9M, а Flightradar — более $2M.

Если в Европе есть Flightradar, в США — Flightaware, то в Китае есть VariFlight. Точно так же сервис, торгует статусами авиарейсов, статистическими данными и архивами рейсов, выполняет анализ и прогнозирование для заказчиков — организаций и индивидуальных клиентов.

Собственными словами VariFlight:

    <meta name="description" content="VariFlight занимает лидирующие позиции среди поставщиков информации о статусе полетов. Мы предоставляем статистические данные, информацию о рейсах в реальном времени, расписание полетов и др. Наши продукты и услуги, такие как Индекс Комфортности Полета, могут быть беспрепятственно интегрированы с деловыми системами и процессами.">
    <meta name="keywords" content="расписание рейсов, онлайн табло аэропорт, домодедово расписание, аэропорт погода, задержка рейса, статус рейса, карта полетов, время вылета, отслеживание рейсов, шереметьево онлайн табло, самолеты онлайн, анализ данных, отслеживание самолетов, воздушный транспорт, аэропорт расписание">
    <meta property="og:url" content="http://www.variflight.com/ru/">

Компании торгуют данными, как своими, так и полученными, например, от Федерального управления гражданской авиации США. Но наибольшую прибыль можно получить от собственных приёмников, эксплуатация которых компании ничего не стоит т.к. они установлены у энтузиастов радарспоттинга, необходимо потратиться только на изготовление и пересылку. Поэтому с какого-то момента компании стали продавать и бесплатно рассылать свои приемники. Бесплатно туда, где у компании нет еще покрытия своей сетью приемников и откуда нет данных.

Стоимость данных оправдывает «бесплатное» распространение приемников (обратите внимание на текст под таблицей — приемник остается в собственности компании Flightaware, формально безоплатно сдается в аренду).


К 2015 году в сети Flightradar было более 8000 активных приемников, у Flightaware — около 4500. Но Flightaware начал распространение приемников за два года до этого, а Flightradar к тому времени строил свою сеть уже почти десять лет. На данное время в сети Flightaware более 15 000 приемников. ПО приемников Flightaware постоянно совершенствуется и на данное время работает с данными FMSDATA, FMSWX.

Карта размещения приёмников в марте 2017 года:

image

Оранжевые — бесплатно распространяемые приемники Flightaware, белые — самодельные приемники, красные — платная программа PlanePlotter.

Это покрытие сети приемников Flightaware в декабре 2015 года:


А в марте 2017 года сеть приемников Flightaware (современное состояние на офсайте) обеспечивала такое покрытие:

image

Не везде есть возможность установить приемники, поэтому в 2018 году данные наземных приемников дополняются данными со спутников Iridium NEXT — «Впервые станет возможно непрерывно отслеживать самолеты в любой точке мира».


Серо-голубой цвет — данные спутников Iridium NEXT. Зеленый и желтый (последний — это MLAT) — данные наземных приемников.

Радиус зоны, которую охватывает одна станция, ограничивается кривизной поверхности Земли и препятствиями закрывающими линию горизонта, и составляет не более 450 км в лучшем случае. А в «обычном случае» около 150 км. При редких тропосферных прохождениях для этой радиочастоты возможно заглянуть за горизонт. Пример зон максимального охвата станций, транслирующих на Planeradar.ru:


Острые пики на диаграммах приема — это как раз единичные случаи приёма на очень больших расстояниях.


Анимация ниже показывает с чем связана необходимость рассылать приёмники. За пределами ЕС/США это хобби мало популярно. Может быть причина в стоимости хобби и эта карта косвенно указывает на уровень благосостояния, на техническое образование, плотность населения в регионе. Возможно дело в практическом интересе — пользователи передающие данные своих приемников получают бесплатный корпоративный аккаунт Flightaware, стоимостью $90 в месяц.


И так в общих чертах обрисована ситуация. Рынок этой услуги растет, рынку необходимо больше данных и VariFlight тоже начал развертывать свою сеть. В апреле 2018 года компания VariFlight сообщила, что ищет добровольцев для размещения бесплатного оборудования. Пример такого сообщения в публикации на Instagram.

А в августе мне на глаза попалось это предложение бесплатно заказать приемник по ссылке http://flightadsb.feeyo.com (Сайт закрыт в сентябре 2019 года — новый сайт flightadsb.variflight.com и ссылка для заказа устройства здесь ). Изучив сайт, я обратил внимание, что компания ищет добровольных участников сети в странах возле границ Китая. И заполнив анкету, особо не рассчитывал, что ЮФО входит в зону интересов компании.


В самой заявке требуется указать на карте место установки (Installation Location), этаж установки антенны на здании (Floor of Installation, например 7/9 — 7 этаж 9-этажного здания), код ближайшего аэропорта (Airport code — я указал код IATA) и загрузить фотографии горизонта с места установки (Installation Environment). В остальном почти совпадает с заказом на Aliexpress, кроме пунктов Title, Nationality, Occupation, Company. Заполняется на английском с ФИО.

Через пару недель проверив почту, обнаружил два email от ADSB展示系统(Display system of ADS-B) о том, что заявка была почти сразу одобрена и что посылка давно мчится ко мне, на тот момент уже миновав таможню.


Во втором письме были логин, пароль и трек-номер посылки. А еще инструкция, которую я не заметил и прочитал, когда… сами знаете, когда обычно читают инструкцию.


Логин соответствовал ФИО в заявке, а пароль явно присылают один и тот же всем. Поэтому идем и меняем пароль сразу (и логин если требуется).

Вообще далее в голове всё чаще всплывала фраза «Это какая-то ерунда» из игры Sudden-strike, если кто помнит как немцы в игре с акцентом говорят на русском языке. Иногда тихо, иногда громко.

Кстати анкета была единственной страницей на английском языке, дальше всё будет на китайском. На Хабре wtigga опубликовал отличную статью о китайском интернете «Китайский интернет и софт: о наболевшем». Я прочувствовал всю боль только сейчас. Если вы не читали, то самое время подготовиться.


Браузер Google Chrome с функцией перевода поможет работать на сайте, но много страниц которые ему оказались не всегда посильны.


Местами будут забавные фразы.


И так логинимся с данными из второго email.


И идем в пункт Личная информация. Как оказалось Google Chrome не всегда может перевести страницу либо ему это удается не с первого раза и в данном случае, после ряда попыток автоматического перевода, пришлось копировать текст в Google Translate. Поэтому размещаю подсказку для тех, кто столкнется с такой же проблемой.

На странице две вкладки, активная из которых отмечена красной чертой. На первой можно ничего не трогать.


  1. ФИО
  2. Ваш номер телефона
  3. Ваш email
  4. Код аэропорта
  5. Название вашего ADSB-приёмника

Пункт QQ — это китайский мессенджер Tencent QQ.

На второй вкладке смена пароля


  1. Старый пароль
  2. Новый пароль
  3. Повтор нового пароля

За исключением этого, автоматический перевод почти всегда срабатывает. Дизайн карты сайта очень близок к сайту Flightradar и «особенности» перевода не затрудняют его использование.


При детальном осмотре сервис отличается, например, интересный функционал, которого нет у Flightaware — тепловая карта, в переводе Google Chrome как «тепловой анализ».


Интересная особенность у некоторых рейсов:


Вероятно отсутствует информация о аэропортах вылета и посадки этого рейса.

Обзор посылки и приёмника


По трек-номеру посылка была отправлена 6 сентября и получена 18 сентября. Коробка имеет солидные размеры, удивившие работников почтового отделения. По дороге из отделения почты внутри что-то гремело, звякало и перекатывалось.


Открытая коробка несколько удивила отсутствием упаковочных материалов.


Для сравнение коробка у приемника Flightaware.


К удивлению содержимое коробки внешне не пострадало. Только на антенне обнаружилась царапина — содрана пленка.


Сам приемник имеет надписи только двух разъемов — питания и HDMI. Кроме двух, все разъемы выведены на одну сторону. LAN, 2 порта USB, четырехконтактный разъем (предположение, что это последовательный интерфейс подтвердилось прозвонкой на BCM 14 (8 pin TXD / Transmit),
BCM 15 (10 pin RXD / Receive)), питание 5 вольт и SMA (female) разъем для антенны.


На противоположной стороне, за двумя отверстиями в корпусе, находятся зеленый и красный светодиоды. И рядом наклейка с «серийным номером» приемника, записанным от руки. Также приемник имеет HDMI и microUSB.


Крышка приемника имеет два уха для крепления на стену, что положительно отличает его от почти такого же корпуса приемника Flightaware, которому производитель предусмотрел только четыре силиконовые ножки на дне.


Проверка возможности использовать эти два уха для монтажа приемника:


Flightaware Flightfeeder вверх днищем:


Для сравнения размеров приёмников:


Естественный вопрос «что же внутри?». Сняв крышку, закрепленную 4 винтами, видим такою компоновку.


Разъемы находятся на отдельной плате приёмника, выполненном в виде платы расширения для Raspberry Pi 3 Model B V1.2.

Для сравнения фотография Flightaware Flightfeeder (G6) без крышки. Это поколение приемников рассылали примерно до 2017 года. Построен на RPi 2 Model B v.1.1 и упрощенном до одного канала приёмнике-декодере Mode-S Beast.


Обратная сторона этой конструкции скрывала неожиданный элемент. Сюрпризом оказывается массивный радиатор, расположенный с нижней стороны платы. Непонятна необходимость в нем (спустя неделю я думаю, что это «тропическое исполнение». В моих условиях радиатор слегка теплый).


Дополнительно плата расширения соединена с RPi четырехконтактным разъемом с тремя проводами, припаянными к тестовым точкам PP27 (USB VCC), PP44 (USB D-),
PP45 (USB D+).


Т.е. в верхний правый разъем USB подключать ничего нельзя. Поэтому на фото корпуса, размещенной выше, видно, что из двух спаренных USB разъемов, прорезь в корпусе только напротив одного, ближнего к LAN.


Так же поступили в Flightaware, припаяв приемник к контактам одного из разъемов.

Большую часть платы расширения занимает металлический экран. Из видимых деталей разъемы на одной стороне, и на противоположной два индикатора и некая «катушка» с отводами. Напоминает шунт с переменным сопротивлением. Возможно 1div0, автор статьи «Зачем гнуть дорожки?» знает что это. При нормальной работе приемника горит зеленый светодиод. В каких случаях горит красный — мне неизвестно. Пока не наблюдал его включение.


На стороне разъемов есть находятся разъемы питания и антенны, и четырехконтактный разъем неизвестного назначения.

Вся электроника скрыта под большой жестяной крышкой экрана. У Flightaware Flightfeeder плата приемника не экранирована. На форуме Flightaware разработчики на этот вопрос ответили, что для защиты от внешних помех достаточно металлического корпуса самого приёмника.


Попытка заглянуть под экран удалась со второго подхода. Крышка отпаялась и оказалось…


… как оказалось всё было зря — маркировка с микросхем старательно спилена.


Забегая вперед, скажу, что это оказался почти обычный RTLSDR приёмник — RTL2832U DVB-T (0bda:2838), называемые «донглами», «свистками», и которым посвящено несколько статей на Хабре, которые дают представление об этих устройствах и том, как они упростили и удешевили реализацию приема и обработки радиосигналов на компьютерах. Например:


В последней хорошо описана история вопроса:
Выход в свет микросхемы RTL2832U для приемников цифрового телевидения в формате DVB-T не обещал никаких сенсаций, ведь фирма Realtek и так несколько запоздала с ее выпуском. В 2010 году уже начинал внедряться более прогрессивный стандарт DVB-T2 с более эффективным кодированием информации, поэтому первоначально новинка не привлекла особого внимания. В течение двух лет дешевые USB-тюнеры на ее базе использовались по своему прямому назначению, пока в начале 2012-го года не произошла утечка некоторой технической информации о режимах работы данного чипа. Выяснилось, что для приема аналогового (FM) и цифрового (DAB) радио в диапазоне УКВ, эта микросхема использует принцип программного декодирования предварительно оцифрованной из эфира полосы частот. Т.е. она, грубо говоря, оцифровывает высокочастотный сигнал из антенного входа, а фильтрация конкретной несущей и ее детектирование (выделение полезной информации) из полученного цифрового потока отдается на откуп центральному процессору. Очевидно, что сделано это было из соображений экономии, точно так же, как во времена заката Dial-UP массовое распространение получили экстремально дешевые «софт-модемы», которые тоже представляли собой лишь продвинутую пару ЦАП+АЦП, а весь сигнальный процессинг выполнялся CPU в потоке с наивысшим приоритетом.

В отличии от «обычных тюнеров», которые есть у меня, у данного экземляра usb id 0bda:2832 и есть 17-значный серийный номер.
Bus 001 Device 005: ID 0bda:2832 Realtek Semiconductor Corp. RTL2832U DVB-T
Found Rafael Micro R820T tuner
Т.е. аналог «синему свистку», используемому при создании самодельных ADSB приемников. На фото приёмник на OrangePI.


Собирая приемник обратно, установил радиатор на всякий случай. Покупались специально для доработки роутеров и другой домашней аппаратуры.


Блок питания 5В 2А. Выглядит солиднее, чем блок питания для Flightaware Flightfeeder. Но с китайской вилкой… Попытался вспомнить, где у меня переходник валяется.


В коробке из белого картона оказался такой симпатичный бархатный мешочек.


"… в сундуке — заяц, в зайце — утка, в утке — яйцо, в яйце — игла..."


Внутри оказалась головоломка из трех адаптеров, которая решила вопрос «где у меня переходник валяется».


В коробке из коричневого картона оказался грозозащитный разрядник «CA-23RP 2.5GHZ 400W Made in Japan». Мне неизвестно о такой комплектации других ADS-B приемников. Очень разумно для защиты от несчастных случаев небольшой мощности.


Комнатная антенна, вероятно, для тестирования приемника без установки внешней антенны. Не годится для практического применения. Но продается на Aliexpress/Ebay как «ADS-B антенна», но её настоящее предназначение выдает надпись на магнитной подошве. У меня на эту антенну ловились самолеты не далее, чем в радиусе 30-40 км.

Рядом переходник N(female) — SMA(male). Возможно подарок на случай подключения фильтра или малошумящего усилителя.


Коаксиальный кабель для антенны 5 метров с разъемами N и SMA, и витая пара 10 метров («100% бескислородная медь, блаблабла»).


Антенный кабель с маркировкой KOPA PLESS RG400-KF MIL-C-17. Гуглится M17/128-RG400 RG-400 Double Braid Flexible Coaxial Cable с другим цветом оболочки:

  • Максимальная рабочая частота 6 GHz
  • На частоте 1.20 GHz максимальное затухание 0.54 dB/m

Очень сомнительно, что это характеристики китайского кабеля. К слову у Flightaware в комплекте был паршивый антенный кабель, хоть и итальянский. Укорачивание кабеля от антенны до нескольких десятков сантиметров раза в три увеличило количество принятых пакетов приемником Flightaware.


Наружная антенна и её крепление к мачте.


Курьёз из группы FlightFeeder ADS-B VariFlight на Facebook:


Антенна чуть меньше диаметром, чем у Flightaware


Крепление к мачте у Flightaware из дюраля


Подарок с символикой VariFlight. Судя по надписям на обороте — этот ярлык следует цеплять на багаж на случай утери в аэропорту, заполнив контактные данные владельца.



Первое включение


Включение питания принципиально ничего не изменило во внешнем виде аппарата. Горели только индикаторы LAN, у роутера в списке выданных IP-адресов dhcp появилось новое имя хоста raspberrypi. На HDMI был обычный вывод загрузки RPi и запрос login.


И всё. Ожидаемый для таких устройств веб-интерфейс по адресу IP:8080 был недоступен. Сканирование портов устройства нашло только порт 22. На попытку войти дефолтным пользователем и паролем был далеко послан и в консоли и в ssh:

login as: pi
pi@raspberrypi's password:
Access denied

Приемник включался и выключался несколько раз, оставался сутками включенным из предположения, что он может что-то в это время скачивать либо пытаться достучаться до серверов в Китае. Ни красный, ни зеленый индикатор не загорались.

В это время я отправился на офсайт в поиске FAQ, техподдержки или еще чего-то, что могло бы рассказать, что это устройство делать должно и не должно. Впервые залогинился, но это принципиально ничего не поменяло — никаких контактных форм или форм обратной связи нет. Единственное, что нашлось — приемник был привязан к аккаунту и имел статус offline. Обратил внимание факт, что система в последний раз его видела в сети 2 сентября в 17.18 пекинского времени, за 4 дня до отправки почтой. Т.е. его проверили и подключили к аккаунту.


Проведя пару дней в брожении по сайтам «китайского интернета», которые какими-то линками ссылались на оффсайт либо на которые вели линки с оффсайта, и устав от их оригинального дизайна, я осознал, что никакой техподдержки у этого изделия нет. И в этот момент я вспомнил о двух email от ADSB展示系统(Display system of ADS-B).

«Это какая-то ерунда» — в очередной раз послышался в голове знакомый голос с акцентом. Мой email на этот адрес завернул обратно PostMaster feeyo.com


И тут глаз зацепился за вложение ко второму письму, ранее ускользавшее от взгляда (из-за непривычного нового дизайна GMail). Это оказалась инструкция об установке VariFlight ADS-B. Самое время узнать как это должно было работать.

Знакомимся с 飞常准 ADS-B 设备安装说明


Ниже перевод инструкции на 6 страницах и двух языках, большую часть которой занимают иллюстрации.

Инструкция по установке VariFlight ADS-B



Краткое описание


VariFlight ADS-B — это оборудование, предназначенное для энтузиастов гражданской авиации для отслеживания воздушных судов. Комплект состоит из ADS-B приёмника, блока питания, коммутационного шнура (патч-корд), антенны и кабеля для неё.


Место установки антенны


Внешняя антенна должна быть закреплена с внешней стороны здания, насколько высоко как это возможно выше препятствий радиосигналу; установка на крыше предпочтительна. В противном случае ADS-B сигналы будут поглощены такими препятствиями, как стена или здание.


После установки антенны, Вам необходимо подключить ADS-B приёмник к интернету, выполнив следующие шаги:

  1. Подключите антенный кабель к приёмнику.
  2. Вставьте один конец патч-корда в роутер и другой конец ADS-B приемника.
  3. Подключите блок питания к приёмнику.


Интернет должен подключиться автоматически, как только вы выполните эти три шага выше. Статический IP не поддерживается, только DHCP.

Комплект оборудования в сборе



Пример с использованием комнатной антенны



Три способа узнать находится ли ваше ADS-B оборудование в состоянии онлайн или нет


Метод первый.
В настройках вашего роутера найдите IP адрес ADS-B приёмника и откройте http//XXX.XXX.XXX:8080 в веб браузере, где XXX.XXX.XXX внутренний IP адрес в вашей локальной сети.


Метод второй

Откройте ссылку flightadsb.variflight.com в веб браузере, авторизуйтесь, и нажмите на пункт Airport


Метод третий, только для китайских добровольцев

Для китайских пользователей возможно использование WeChat.


На этом инструкция закончилась. В соответствии с этой инструкцией устройство работает частично — получает IP в локальной сети, но не отображает вебинтерфейс, в котором можно узнать dump1090 — декодер Mode S, созданный для RTLSDR донглов и используемый в подобных устройствах.

image

Без работающего dump1090 никаких данных на сервер не поступит. Странно, что устройство как-то работало при проверке перед отправкой. «Это какая-то ерунда». Раз китайцы никак не интересуются судьбой устройства, и никаких признаков техподдержки найти не удалось, то совесть моя совершенно чиста, если я попробую его отремонтировать самостоятельно.

Берем устройство под свой контроль


Разобрав приемник, сразу же при получении, я сделал образ microSD в состоянии до первого включения и немного изучил содержимое, сразу заподозрив как приемник отдает данные на сервер — в /root/ находились файлы и скрипты с адресами сервиса.

Сброс пароля пользователя PI


Инструкцию о смене «забытого пароля» с картинками можно найти по этой ссылке.

Разбираю еще раз приемник. Чтобы добраться до microSD надо открутить все винты и вытащить обе платы. В дальнейшем, работая с приёмником, я не собирал обратно в корпус т.к. приходилось сменять две microSD с разными системами.

Вытаскиваем microSD из Rpi, на компьютере делаем резервную копию, если еще не делали, и редактируем файл — cmdline.txt.

dwc_otg.lpm_enable=0 console=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

В конец этой строки добавляем

init=/bin/sh

Возвращаем microSD обратно в RPi, подключаем монитор и клавиатуру. Подключаем питание. Когда по экрану перестают бежать строки, нажимаем Enter. Появляется приглашении консоли, в которой набираем

mount -rw -o remount /
passwd pi
sync
exec /sbin/init

Снова бегут строки и снова ждем, когда они перестанут бежать, после чего выключаем. Достаем microSD из RPi. На компьютере редактируем либо восстанавливаем резервную копию cmdline.txt — удаляем «init=/bin/sh».

В последний раз возвращаем microSD обратно в RPi. Включаем. Успешно логинимся с новым паролем. Включаем ssh введя raspi-config и выбрав в меню SSH.

Затем командой top хочу посмотреть, чем живет приёмник и неожиданно замечаю процессы wget и… dump-1090. Немая сцена. Проверяю в веб браузере http//XXX.XXX.XXX:8080 — есть интерфейс.


Не сказать, что неожиданно, но точно непривычно. Из инструкции проверяю Метод второй — там тоже всё хорошо: значок приёмника позеленел, а ниже появился список самолетов, которые он услышал.

Можно было бы на этом бы и закончить, но во-первых использовать RPi3 только для этого было бы непростительно. А во-вторых, если бы это устройство стабильно работало. Например, пропало из списка IP адресов DHCP роутера, при этом было доступно при обращении по полученному ранее IP, и одновременно не было изображения на HDMI. Но самым важным оказалась нестабильность вещания. Согласно статистике на странице приемника, он работал несколько часов в сутки. Иногда полные сутки, иногда несколько часов, иногда ноль часов. Несколько дней ушло на изучение системы — не всякий софт устанавливался. Китайские репозитории… Немецкий голос окончательно убедил, что надо сделать ADS-B приёмник здорового человека, а для этого надо накатить на другую microSD образ PiAware. Оригинальная microSD еще пригодилась для выяснения как это работает. Как минимум сохраните файлы из /root. Желательно сделайте образ.

PiAware


PiAware — программное обеспечение Linux для передачи полетных данных на FlightAware. Содержит форк dump1090-mutability. Со слов разработчиков, одно из отличий, что не посылает на сервера FlightAware пакеты, если в них нет отличий от первого. Т.е. если самолет не изменил скорость, высоту, то эти данные обрабатывать не надо, и таким образом снижает нагрузку на сервера.

Примерно два года назад FlightAware начал перевод текстов на сайте на русский язык. И многое по созданию собственной станции PiAware можно найти офсайте. Суть создания станции на RPi с RTLSDR сводится к записи на microSD готового образа PiAware on Raspbian Linux с помощью программы Etcher. Далее, прежде чем вставить карту в RPi и дождаться загрузки, необходимо внести некоторые изменения. Для того чтобы включить доступ SSH создайте пустой файл без расширения с именем ssh в загрузочном разделе (/boot partition). А в файл piaware-config.txt можно внести необходимые настройки, например, указать статический IP или включить WiFi и указать SSID/пароль, при условии, что подключен поддерживаемый USB WiFi адаптер. Эти же настройки можно выполнить из консоли командой piaware-config Setting_name Possible_values.

Если у Вас уже есть аккаунт Flightaware, то через 5 минут станция привяжется к аккаунту, получив Unique Identifier. И у приемника появится собственная страница со статистикой.

По умолчанию пользователь PI имеет пароль flightaware. Хорошей идеей будет сразу же сменить пароль.

«Испытания»


Испытания именно в кавычках, просто впечатления. Имея два устройства с почти одинаковым ПО можно оценить их способности.

У меня есть бесплатный приемник Flightaware и первое, что я испытал, была комплектная VariFlight антенна. Я просто заменил на неё антенну Flightaware. И пока изучал VariFlight приёмник, на странице Flightaware собиралась статистика FlightFeeder. Вывод неутешительный. Хотя по максимальной дальности ничего не изменилось, как и FlightFeeder, в направлении прямой видимости, ловя некоторые на расстоянии 400 км, но статистика самолетов в час/сутки просела в 2-3 раза. Уверено принимает борта на 300+ километров, но видит немного меньше сообщений. Что внутри корпуса самой антенны не знаю — не разборная.

К приемнику VariFlight была подключена антенна Flightaware и он показал статистику того же порядка. А с родной антенной еще ниже.


Расшифрую статистику. Статистика с 10-05 по 10-07 — это приемник VariFlight с антенной Flightaware. 10-08 была подключена комплектная антенна и с 10-09 по 10-11 статистика комплекта VariFlight. 10-12 изменен скрипт send_message.py на сбор данных с Flightaware Flightfeeder. После этого на VariFlight пошли данные с него и 10-13 — суточная статистика на основе данных Flightaware Flightfeeder. Далее больше, например, за 10-18 — 396 рейсов, 814176 пакетов, за 10-19 — 471 рейсов, 860415 пакетов.

Оценим насколько приемник VariFlight подвержен радиопомехам. Для этого просканируем диапазон 800МГц-1200МГц и сгенерируем тепловую карту.

sudo apt-get install python-imaging
sudo wget https://raw.githubusercontent.com/keenerd/rtl-sdr-misc/master/heatmap/heatmap.py
sudo chmod +x heatmap.py
sudo systemctl stop dump1090-fa
sudo rtl_power -f 800M:1200M:100k -i 30 -c 50% -e 30m -g 30 -F 9 >scan.csv

Через полчаса (-e 30m) сканирование прекращается и генерируем изображение.
./heatmap.py scan.csv scan.png

Перезагружаем устройство для восстановления работы dump1090.
И копируем полученное изображение на компьютер с помощью (win)scp.
Это фрагмент тепловой карты сканирования около частоты 1090 МГц. Полное изображение доступно по клику.



Яркие желтые полосы — это мобильная связь. Ничего необычного — у него нет никаких префильтров как у Flightfeeder, и ему сильно мешают станции мобильной связи. В этом он абсолютно такой же как простой «синий свисток» упоминавшийся ранее. Возможно изготовление в виде специальной платы расширения имеет какой-то смысл, например, непонятна роль «гнутых дорожек» на этой плате. Изготавливая специализированную плату было бы не сложно установить и малошумящий усилитель и ПАВ-фильтр на 1090 МГц. Только посмотрев скрипты в устройстве, у меня появилась мысль зачем это сделано — один скрипт называется acars.py.


Насколько бы усилитель и фильтр бы улучшил характеристики приемника показывает пример из упомянутой выше группы на Facebook. Один из пользователей VariFlight Box подключил вместо штатного приемника специализированный донгл от Flightaware, что вывело его в топ рейтинга из примерно тысячи пользователей (конечно еще повлияло место установки и другая антенна).

FlightAware выпускает две модели донглов — Pro Stick и Pro Stick Plus, являющимися всё тем же «синим свистком», но имеющими предварительный усилитель сигнала, и в последнем дополнительно установлен ПАВ-фильтр, который обеспечивает устранение ненужных сигналов в районах с большим количеством помех, например в городах, а также эти модели оборудованы антенным разъемом SMA. Эти донглы используются в «оранжевых» приемниках Flightaware Flightfeeder.


со снятой крышкой


Название скрипта «acars.py» намекает, что отсутствие каких либо фильтров не является ошибкой и экономией. Адресно-отчётная система авиационной связи (англ. Aircraft Communications Addressing and Reporting System, ACARS) — цифровая система радиосвязи, применяемая в авиации для передачи коротких сообщений между летательным аппаратом и наземными станциями. Рабочая частота для ACARS в Европе — 131,725 МГц. Поэтому устройство не может иметь фильтр только для 1090МГц, иначе не сможет принять сигнал на 131 МГц. Что внутри антенны — неизвестно, ломать её не собираюсь, но очевидно, что её «широкоохватность» так же предусмотрена создателями. Аналогично способу выше сгенерировал тепловую карту в диапазоне 100 МГц-500 МГц. Фрагмент тепловой карты сканирования около частоты 450 МГц. Полное изображение также доступно по клику.



На тепловой карте видны пульты управления, охранные датчики, беспроводные дверные звонки, беспроводные датчики метеостанций, радиолюбители, ФМ-радиостанции, и прочее, и прочее.

Например, установив rtl_433 можно увидеть данные соседских беспроводных датчиков метеостанций и при желании ими воспользоваться как автор этой статьи.


А запустив rtl_tcp можно послушать радиолюбителей и ФМ-радио.


Интересно, что не у всех радиолюбителей рация точно держит частоту. Забавно было видеть, как радиолюбители оценивали как слышно собеседника, а частота одной из радиостанций была где-то в стороне.

А вот сам китайский приемник на родной системе показал точность — 0 PPM. Об методике измерения PPM можно прочитать на Хабре в статье quwy «Еще раз о приеме КВ на RTL-SDR». Очень желательно откорректировать PPM для наилучшего приема. Что и сделали китайцы. На Piaware есть небольшая ошибка, которую можно и нужно убрать, указав правильное значение PPM командой sudo piaware-config rtlsdr-ppm <значение PPM>.
Инструкция по калибровке RTLSDR с помощью rtl_test и kalibrate-rtl
 rtl_test -p 

Ждем около 10 минут, пока значения не стабилизируется. Это будет искомый ppm.

Повысить точность можно по сигналам вышек мобильной связи с помощью утилиты kalibrate-rtl.
sudo apt-get install libtool autoconf automake libfftw3-dev
git clone https://github.com/asdil12/kalibrate-rtl.git
cd kalibrate-rtl
git checkout arm_memory
./bootstrap
./configure
make
sudo make install
kal -s GSM900

Из списка каналов необходим тот, у кого значение «power» больше.
Полученный номер канала используем в команде kal -c <номер канала> -e <грубое значение PPM, определенное ранее вручную или утилитой rtl_test> -v
В результате получаем «average absolute error». И используем это значение ppm, округленное до целого, в команде sudo piaware-config rtlsdr-ppm <значение PPM>


В качестве итога можно сказать, что приемник VariFlight по железу немногим лучше, чем то, что можно собрать самостоятельно. Это хорошая база, чтобы начать заниматься этим хобби (и показало испытания железа, его можно применить для широкого спектра других задач. Тем более есть три свободных USB порта).

Однозначный недостаток как ADSB-приемника — ПО и китайский интерфейс сайта. Если с китайским сайтом сделать ничего нельзя, то можно доработать ПО самого приёмника. Наиболее легкий способ — это установить PiAware и настроить раздачу на VariFlight. Затем можно настроить раздачу на Flightradar24 и получить аккаунт с особыми условиями и там. Пример использования аккаунта с особыми возможностями — доступ к архивным данным Flightaware (крушение Ан-148 «Саратовских авиалиний»).
image


Отдаем данные на VariFlight


Возвращаемся к содержимому каталога root. Его можно найти на GitHub. Названия файлов однозначно намекают на их функции.

root@raspberrypi:/home/pi# ls /root -l
total 24
drwxr-xr-x 8 root root 4096 Nov 22  2016 dump1090
drwxr-xr-x 5 root root 4096 Oct 16 18:54 get_message
-rwxr-xr-x 1 root root  567 Nov 22  2016 install.sh
drwxr-xr-x 7 root root 4096 Nov 22  2016 rtl-sdr
-rwxr-xr-x 1 root root   62 Nov 22  2016 synctime.sh
-rwxr-xr-x 1 root root 1300 Nov 29  2016 task.sh

install.sh
#!/bin/bash
apt-get update
apt-get install cmake libusb-1.0-0-dev build-essential vim ntpdate -y
apt-get remove ntp

cd get_message/
mv rtl-sdr-blacklist.conf /etc/modprobe.d/
mv dump.sh /etc/init.d/dump
chmod +x /etc/init.d/dump
mv task.sh ../
chmod +x ../task.sh
cd ../rtl-sdr/
mkdir rtl
cd rtl
cmake ../ -DINSTALL_UDEV_RULES=ON
make install
ldconfig
cd ../../dump1090/
make
cd /root/get_message/

python get_ip.py 
ps aux | grep py
update-alternatives --config editor
crontab -e
* * * * * /root/task.sh >/dev/null 2>&1
* * */6 * * /root/synctime.sh >/dev/null 2>&1


Из последних строк install.sh видно, что cron добавляются два задания — запускать каждую минуту task.sh и каждые 6 дней synctime.sh

synctime.sh
#!/bin/bash
/usr/sbin/ntpdate 115.182.42.248 > /dev/null 2>&1


115.182.42.248 — BeiJing wanglianxuntong Telecom Technology Co.,Ltd, Beijing, China.
remarks: Please note that CNNIC is not an ISP and is not
remarks: empowered to investigate complaints of network abuse.
remarks: Please contact the tech-c or admin-c of the network.
task.sh

#!/bin/bash
ps -eaf | grep dump1090 | grep -v grep
if [ $? -eq 1 ]
then
/etc/init.d/dump stop
sleep 1
/etc/init.d/dump start
echo `date "+%G-%m-%d %H:%M:%S"`" dump1090            restart"
echo "------------------------------------------------------------------------"
else
echo `date "+%G-%m-%d %H:%M:%S"`" dump1090            running"
echo "------------------------------------------------------------------------"
fi

ps -eaf | grep send_message.py | grep -v grep
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
python -O /root/get_message/send_message.py &
echo `date "+%G-%m-%d %H:%M:%S"`" send_message            restart"
echo "------------------------------------------------------------------------"
else
echo `date "+%G-%m-%d %H:%M:%S"`" send_message            running"
echo "------------------------------------------------------------------------"
fi

ps -eaf | grep get_ip.py | grep -v grep
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
python /root/get_message/get_ip.py
echo `date "+%G-%m-%d %H:%M:%S"`" get_ip            restart"
echo "------------------------------------------------------------------------"
else
echo `date "+%G-%m-%d %H:%M:%S"`" get_ip            running"
echo "------------------------------------------------------------------------"
fi


Скрипт task.sh, запускаемый ежеминутно cron-ом, проверяет и при необходимости перезапускает dump1090, скрипты send_message.py и get_ip.py.

pi@raspberrypi:~ $ ps -eaf | grep dump1090 | grep -v grep
root       830     1 14 Oct12 ?        13:49:25 ./dump1090 --net --net-sbs-port 30003
pi@raspberrypi:~ $ ps -eaf | grep get_ip.py | grep -v grep
pi@raspberrypi:~ $ ps -eaf | grep send_message.py | grep -v grep
root       838     1  0 Oct12 ?        00:09:20 python -O /root/get_message/send_message.py

В каталоге get_message находятся скрипты python, один из которых, send_message.py, отправляет данные.

root@raspberrypi:/home/pi# ls /root/get_message  -l
total 40
-rw-r--r-- 1 root root  954 Nov 22  2016 acars.py
-rw-r--r-- 1 root root 1341 Nov 22  2016 acars.sh
-rw-r--r-- 1 root root  173 Nov 22  2016 config.ini
drwxr-xr-x 8 root root 4096 Nov 22  2016 dump1090
-rwxr-xr-x 1 root root 1731 Nov 22  2016 get_ip.py
drwxr-xr-x 3 root root 4096 Nov 22  2016 get_message1117
-rwxr-xr-x 1 root root 3400 Dec  7  2016 init.sh
-rw-r--r-- 1 root root   33 Oct 16 18:51 md5.txt
-rwxr-xr-x 1 root root 1143 Oct 12 18:16 send_message.py
-rw-r--r-- 1 root root   16 May 27  2016 UUID

init.sh
#!/bin/bash

path='/root/get_message/'
DATE=`date -d "today" +"%Y-%m-%d_%H:%M:%S"`
result=""
UUID=""
execom=""
FromServer=""
SourceMD5=""
device=""

if ps -ef |grep dump1090 |grep -v grep >/dev/null
then
        device="adsb"
elif ps -ef |grep acarsdec |grep -v grep >/dev/null
then
        device="acars"
else
        device="unknow"
fi

IpAddr=`/sbin/ifconfig |grep "addr:" |grep -v 127.0.0.1 |cut -d ':' -f2 |cut -d ' ' -f1`

if [ -f "/root/get_message/UUID" ]
then
        UUID=`cat /root/get_message/UUID`
fi

execut(){
        while read command
        do
                eval $command
                if [  $? -ne 0 ]
                then
                        execom=$command
                        result=0
                        break
                fi
                result=1
        done <$path/package/exe.txt
}

removefile(){
        rm -rf $path/package
        rm -f $path/*tar.gz*
}

main(){
	ps -eaf | grep "pic.veryzhun.com/ADSB/update/newpackage.tar.gz" | grep -v grep
	if [ $? -eq 1 ]
	then
		/usr/bin/wget -P $path -c -t 1 -T 2 pic.veryzhun.com/ADSB/update/newpackage.tar.gz
        	if [ -f "$path/newpackage.tar.gz" ]
        	then
                	dmd5=`md5sum $path/newpackage.tar.gz|cut -d ' ' -f1`
                	if [ "$SourceMD5" = "$dmd5" ]
                	then
                        	/bin/tar -xzf $path/newpackage.tar.gz -C $path
                        	echo $SourceMD5 > $path/md5.txt
                        	/bin/touch /usr/src/start.pid
                        	echo $DATE > /usr/src/start.pid
                        	execut
                        	if [ $result -eq 1 ]
                        	then
                                	curl -m 2 -s -d UUID=$UUID -d date=$DATE -d execom=$execom -d message="success" http://receive.cdn35.com/ADSB/result.php
                        	else
                                	curl -m 2 -s -d UUID=$UUID -d date=$DATE -d execom=$execom -d message="fail" http://receive.cdn35.com/ADSB/result.php
                        	fi
                        	removefile
                	else
                        	curl -m 2 -s -d UUID=$UUID -d date=$DATE -d execom="------" -d message="post file has been changed" http://receive.cdn35.com/ADSB/result.php
                        	removefile
                	fi
        	else
                	curl -m 2 -s -d UUID=$UUID -d date=$DATE -d execom="------" -d message="download failed" http://receive.cdn35.com/ADSB/result.php
                	removefile
        	fi
	fi
}

if curl -m 2 -s pic.veryzhun.com/ADSB/update.php >/dev/null;then
	removefile
        FromServer=`curl -m 2 -s -d UUID="$UUID" -d IpAddr="$IpAddr" -d Device="$device" pic.veryzhun.com/ADSB/update.php`
        SourceMD5=`echo $FromServer|cut -d ' ' -f1`
	length=`echo $SourceMD5 |wc -L`
        if [ $length -ne 32 ]
        then
                curl -m 2 -s -d UUID=$UUID -d date=$DATE -d execom="------" -d message="md5 style error" http://receive.cdn35.com/ADSB/result.php
		exit
        fi
else
        curl -m 2 -s -d UUID=$UUID -d date=$DATE -d execom="------" -d message="curl failed" http://receive.cdn35.com/ADSB/result.php
        exit
fi

DesMD5=`cat $path/md5.txt`
if [ "$SourceMD5" = "$DesMD5" ]
then
        curl -m 2 -s -d UUID=$UUID -d date=$DATE -d execom="------" -d message="no update,md5 without change " http://receive.cdn35.com/ADSB/result.php
        exit
else
        main
fi


Скрипт init.sh проверяет есть ли обновление и устанавливает новый send_message.py
get_ip.py
import socket
import fcntl
import struct
import urllib2
import urllib
import sys,os
import ConfigParser
import hashlib
import json
import uuid

config = ConfigParser.ConfigParser()
config.readfp(open(sys.path[0]+'/config.ini',"rb"))

uuid_file=sys.path[0]+'/UUID'

if os.path.exists(uuid_file) :
	file_object = open(uuid_file)
	mid = file_object.read()
	file_object.close()
else :
	mid = uuid.uuid1().get_hex()[16:]
	file_object = open(uuid_file , 'w')
	file_object.write( mid )
	file_object.close()

def send_message(source_data):
	source_data=source_data.replace('\n','$$$')
	f=urllib2.urlopen(
			url = config.get("global","ipurl"),
			data =  source_data,
			timeout = 60
			)
	tmp_return=f.read()

	request_json=json.loads(tmp_return)
	request_md5=request_json['md5']
	del request_json['md5']
	
	
	tmp_hash=''
	for i in request_json:
		if tmp_hash=='' :
			tmp_hash=tmp_hash+request_json[i]
		else :
			tmp_hash=tmp_hash+','+request_json[i]
		
	md5=hashlib.md5(tmp_hash.encode('utf-8')).hexdigest()
	
	if (md5 == request_md5):
		operate(request_json)
	else :
		print 'MD5 ERR'

	print "return: "+tmp_return;

def get_ip_address(ifname):
    skt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    pktString = fcntl.ioctl(skt.fileno(), 0x8915, struct.pack('256s', ifname[:15]))
    ipString  = socket.inet_ntoa(pktString[20:24])
    return ipString
    
def operate(request_json):
	if request_json['type'] == 'reboot' :
		os.system('/sbin/reboot')
	elif request_json['type'] == 'code' :
		fileHandle = open ( urllib.unquote( request_json['path'] ) , 'w' )
		fileHandle.write( urllib.unquote( request_json['content'] ) )
		fileHandle.close()
	else :
		print 'OK'
	
eth=get_ip_address('eth0')

send_message(mid+'|'+eth+'|')


Смысл сетевого обмена, выполняемого скриптом, я особо не понимаю. Генерируется уникальный идентификатор UUID, если он отсутствует. И происходит некий обмен с адресами, указанными в файле config.ini. Вероятно именно этот скрипт отвечает за привязку транслируемых данных и IP с аккаунтом.

Примечательна строка «if request_json['type'] == 'reboot': os.system('/sbin/reboot')».

[global]
name = NEW
ipurl = http://receive.cdn35.com/ADS-B_IP.php
sendurl = http://adsb.feeyo.com/adsb/ReceiveCompressADSB.php
version = 1.0
passwd = 'null'

И наконец скрипт отправляющий данные
send_message.py
import socket
import urllib2
import urllib
import sys
import ConfigParser
import zlib
import base64
import os,uuid

serverHost = 'localhost'
serverPort = 30003

config = ConfigParser.ConfigParser()
config.readfp(open(sys.path[0]+'/config.ini',"rb"))

uuid_file=sys.path[0]+'/UUID'

if os.path.exists(uuid_file) :
        file_object = open(uuid_file)
        mid = file_object.read()
        file_object.close()
else :
        mid = uuid.uuid1().get_hex()[16:]
        file_object = open(uuid_file , 'w')
        file_object.write( mid )
        file_object.close()


sockobj = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sockobj.connect((serverHost,serverPort))

def send_message(source_data):
	try:
		source_data=base64.b64encode(zlib.compress(source_data))
		f=urllib2.urlopen(url = config.get("global","sendurl"),data =  urllib.urlencode({'from':mid,'code':source_data}),timeout = 2)
		return True
	except Exception,e:
		print str(e)
		return True

tmp_buf=''

while 1:
	buf = sockobj.recv(1024)
	if not buf: break
	if len(buf) != 0:
		tmp_buf=tmp_buf+buf
		if buf[len(buf)-1] == '\n':
			if send_message(tmp_buf) :
				tmp_buf=''
				


Строку serverHost = 'localhost' я отредактировал, заменив 'localhost' на 'ff-1234' — сетевое имя моего Flightaware Flightfeeder и перезагрузив приемник VariFlight. После этого на VariFlight пошли данные с Flightfeeder.

Оставшиеся скрипты — это приём сообщений ACARS. Возможно остатки какого-то функционала или реализуемая в будущем функция. Скрипты работают с /root/acarsdec-3.0/acarsdec, который отсутствует по этому пути. ACARSDEC — это ACARS SDR decoder, декодирующий сообщения, например, на частоте 131,725МГц. Судя по всему именно из расчета на прием этой частоты, на входе приёмника отсутствуют фильтры на 1090 МГц.


Адресно-отчётная система авиационной связи (ACARS) — цифровая система связи, применяемая в авиации для передачи коротких, относительно простых сообщений между летательным аппаратом и наземными станциями, либо через прямую радиосвязь, либо через спутниковые системы.
Подробнее о ACARS можно посмотреть, например, здесь.

Скрипт acars.sh по реализации аналогичен task.sh — перезапускает acarsdec и скрипты get_ip.py и acars.py, если не обнаруживает необходимый процесс.

acars.sh
#!/bin/bash
ps -eaf | grep acarsdec | grep -v grep
if [ $? -eq 1 ]
then
/root/acarsdec-3.0/acarsdec -n 127.0.0.1:8888 -o 0 -p -8 -r 0 127.272 126.475 &
echo `date "+%G-%m-%d %H:%M:%S"`" acarsdec            restart"
echo "------------------------------------------------------------------------"
else
echo `date "+%G-%m-%d %H:%M:%S"`" acarsdec            running"
echo "------------------------------------------------------------------------"
fi

ps -eaf | grep get_ip.py | grep -v grep
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
python /root/get_message/get_ip.py
echo `date "+%G-%m-%d %H:%M:%S"`" get_ip            restart"
echo "------------------------------------------------------------------------"
else
echo `date "+%G-%m-%d %H:%M:%S"`" get_ip            running"
echo "------------------------------------------------------------------------"
fi

ps -eaf | grep acars.py | grep -v grep
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
python /root/get_message/acars.py
echo `date "+%G-%m-%d %H:%M:%S"`" acars            restart"
echo "------------------------------------------------------------------------"
else
echo `date "+%G-%m-%d %H:%M:%S"`" acars            running"
echo "------------------------------------------------------------------------"
fi

/usr/sbin/ntpdate cn.pool.ntp.org > /dev/null


acars.py

#!/usr/bin/env python
import socket, traceback ,time,urllib2,urllib,sys,ConfigParser

def send_message(source_data):
	try:
		f=urllib2.urlopen(url = config.get("global","sendurl"),data =  urllib.urlencode({'from':config.get("global","name"),'code':source_data}),timeout = 10)
		print "return: "+f.read();
		return True
	except Exception,e:
		print str(e)
		return False
		
		
host = '127.0.0.1'
port = 8888

config = ConfigParser.ConfigParser()
config.readfp(open(sys.path[0]+'/config.ini',"rb"))


s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind((host, port))

while 1:
     try:
         message, address = s.recvfrom(8192)
         socket_udp_str='{0} :{1} \n\n'.format(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())),message)
         send_message(socket_udp_str)
     except (KeyboardInterrupt, SystemExit):
         raise
     except:
         traceback.print_exc()


В работе это выглядит так:


PID TTY      STAT   TIME COMMAND
20726 ?        Ss     0:00  \_ sshd: pi [priv]
20732 ?        S      0:00      \_ sshd: pi@pts/0
20734 pts/0    Ss     0:00          \_ -bash
20744 pts/0    R+     0:00              \_ ps -afx
  777 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
  907 ?        Sl   737:23 ./dump1090 --net --net-sbs-port 30003
  915 ?        S     11:11 python -O /root/get_message/send_message.py

ps -afx полностью

pi@raspberrypi:~ $ ps -afx
  PID TTY      STAT   TIME COMMAND
    2 ?        S      0:00 [kthreadd]
    3 ?        S      0:59  \_ [ksoftirqd/0]
    5 ?        S<     0:00  \_ [kworker/0:0H]
    7 ?        S      5:28  \_ [rcu_sched]
    8 ?        S      0:00  \_ [rcu_bh]
    9 ?        S      0:01  \_ [migration/0]
   10 ?        S      0:01  \_ [migration/1]
   11 ?        S      0:05  \_ [ksoftirqd/1]
   13 ?        S<     0:00  \_ [kworker/1:0H]
   14 ?        S      0:01  \_ [migration/2]
   15 ?        S      0:04  \_ [ksoftirqd/2]
   17 ?        S<     0:00  \_ [kworker/2:0H]
   18 ?        S      0:01  \_ [migration/3]
   19 ?        S      0:04  \_ [ksoftirqd/3]
   21 ?        S<     0:00  \_ [kworker/3:0H]
   22 ?        S      0:00  \_ [kdevtmpfs]
   23 ?        S<     0:00  \_ [netns]
   24 ?        S<     0:00  \_ [perf]
   25 ?        S      0:00  \_ [khungtaskd]
   26 ?        S<     0:00  \_ [writeback]
   27 ?        S<     0:00  \_ [crypto]
   28 ?        S<     0:00  \_ [bioset]
   29 ?        S<     0:00  \_ [kblockd]
   31 ?        S<     0:00  \_ [rpciod]
   32 ?        S      0:00  \_ [kswapd0]
   33 ?        S<     0:00  \_ [vmstat]
   34 ?        S      0:00  \_ [fsnotify_mark]
   35 ?        S<     0:00  \_ [nfsiod]
   44 ?        S<     0:00  \_ [kthrotld]
   46 ?        S<     0:00  \_ [bioset]
   47 ?        S<     0:00  \_ [bioset]
   48 ?        S<     0:00  \_ [bioset]
   49 ?        S<     0:00  \_ [bioset]
   50 ?        S<     0:00  \_ [bioset]
   51 ?        S<     0:00  \_ [bioset]
   52 ?        S<     0:00  \_ [bioset]
   53 ?        S<     0:00  \_ [bioset]
   54 ?        S<     0:00  \_ [bioset]
   55 ?        S<     0:00  \_ [bioset]
   56 ?        S<     0:00  \_ [bioset]
   57 ?        S<     0:00  \_ [bioset]
   58 ?        S<     0:00  \_ [bioset]
   59 ?        S<     0:00  \_ [bioset]
   60 ?        S<     0:00  \_ [bioset]
   61 ?        S<     0:00  \_ [bioset]
   62 ?        S<     0:00  \_ [bioset]
   63 ?        S<     0:00  \_ [bioset]
   64 ?        S<     0:00  \_ [bioset]
   65 ?        S<     0:00  \_ [bioset]
   66 ?        S<     0:00  \_ [bioset]
   67 ?        S<     0:00  \_ [bioset]
   68 ?        S<     0:00  \_ [bioset]
   69 ?        S<     0:00  \_ [bioset]
   70 ?        S<     0:00  \_ [VCHIQ-0]
   71 ?        S<     0:00  \_ [VCHIQr-0]
   72 ?        S<     0:00  \_ [VCHIQs-0]
   73 ?        S<     0:00  \_ [iscsi_eh]
   74 ?        S<     0:00  \_ [dwc_otg]
   75 ?        S<     0:00  \_ [DWC Notificatio]
   77 ?        S      0:00  \_ [irq/92-mmc1]
   78 ?        S      0:00  \_ [VCHIQka-0]
   79 ?        S<     0:00  \_ [SMIO]
   80 ?        S<     0:00  \_ [deferwq]
   83 ?        S<     0:00  \_ [bioset]
   84 ?        S      0:11  \_ [mmcqd/0]
   87 ?        S      0:04  \_ [jbd2/mmcblk0p2-]
   88 ?        S<     0:00  \_ [ext4-rsv-conver]
   89 ?        S<     0:00  \_ [ipv6_addrconf]
  172 ?        S    415:15  \_ [w1_bus_master1]
  224 ?        S<     0:00  \_ [cfg80211]
  227 ?        S<     0:00  \_ [brcmf_wq/mmc1:0]
  229 ?        S      0:00  \_ [brcmf_wdog/mmc1]
  493 ?        S<     0:00  \_ [kworker/1:1H]
  550 ?        S<     0:00  \_ [kworker/3:1H]
  632 ?        S<     0:00  \_ [kworker/u9:0]
  633 ?        S<     0:00  \_ [hci0]
  634 ?        S<     0:00  \_ [hci0]
  638 ?        S<     0:00  \_ [kworker/u9:2]
 3856 ?        S<     0:00  \_ [kworker/2:1H]
 9346 ?        S<     0:00  \_ [kworker/0:1H]
15564 ?        S      0:00  \_ [kworker/1:0]
17556 ?        S      0:00  \_ [kworker/u8:2]
17878 ?        S      0:00  \_ [kworker/0:0]
17879 ?        S      0:00  \_ [kworker/2:2]
19234 ?        S      0:00  \_ [kworker/u8:4]
19566 ?        S      0:00  \_ [kworker/3:1]
20143 ?        S      0:00  \_ [kworker/2:1]
20259 ?        S      0:00  \_ [kworker/3:2]
20352 ?        S      0:00  \_ [kworker/0:2]
20416 ?        S      0:00  \_ [kworker/1:2]
20600 ?        S      0:00  \_ [kworker/3:0]
20601 ?        S      0:00  \_ [kworker/2:0]
20605 ?        S      0:00  \_ [kworker/u8:0]
20725 ?        S      0:00  \_ [kworker/0:1]
    1 ?        Ss     0:10 /sbin/init
  134 ?        Ss     1:00 /lib/systemd/systemd-journald
  136 ?        Ss     0:08 /lib/systemd/systemd-udevd
  416 ?        Ss     0:09 /usr/sbin/cron -f
  426 ?        Ss     0:01 /lib/systemd/systemd-logind
  429 ?        Ss     0:00 avahi-daemon: running [raspberrypi.local]
  458 ?        S      0:00  \_ avahi-daemon: chroot helper
  433 ?        Ss     0:00 /usr/bin/dbus-daemon --system --address=systemd: --no
  450 ?        Ss     0:02 /usr/sbin/thd --daemon --triggers /etc/triggerhappy/t
  496 ?        Ss     0:03 /sbin/wpa_supplicant -s -B -P /run/wpa_supplicant.wla
  498 ?        Ssl    0:13 /usr/sbin/rsyslogd -n
  636 ?        S      0:00 /usr/bin/hciattach /dev/serial1 bcm43xx 921600 noflow
  640 ?        Ss     0:00 /usr/lib/bluetooth/bluetoothd
  729 ?        Ss     0:02 /sbin/dhcpcd -q -w
  749 ?        Ss     0:00 /usr/sbin/sshd -D
20726 ?        Ss     0:00  \_ sshd: pi [priv]
20732 ?        S      0:00      \_ sshd: pi@pts/0
20734 pts/0    Ss     0:00          \_ -bash
20744 pts/0    R+     0:00              \_ ps -afx
  777 tty1     Ss+    0:00 /sbin/agetty --noclear tty1 linux
  907 ?        Sl   737:23 ./dump1090 --net --net-sbs-port 30003
  915 ?        S     11:11 python -O /root/get_message/send_message.py


Из этого видно, что можно забирать данные с PiAware почти не напрягаясь, фактически, только перенеся скрипты на новую систему. А если уже есть существующая adsb-станция — самодельная, Flightradar24, Flightaware, то имеющийся приемник можно использовать по своему усмотрению на другие личные цели и задачи с совершенно чистой совестью.

Установка VariFlight на PiAware


Переносим в новую систему из старой необходимые файлы. Т.е. содержимое каталога root:
Каталог get_message и файлы install.sh, synctime.sh, task.sh.

В каталоге get_message:
  • acars.py
  • acars.sh
  • config.ini
  • get_ip.py
  • init.sh
  • send_message.py

и файл UUID — ваш идентификатор в сети VariFlight.

Если вы хотите начать делиться данными не имея VariFlight Feeder, то при первом запуске скрипта генерируется ваш UUID. Этот файл и название ближайшего аэропорта необходимо отослать на chengyi(at)variflight.com для создания вашего аккаунта на сервисе.

Далее:

pi@piaware:~ $ sudo apt-get install -y python ntpdate
pi@piaware:~ $ su
root@piaware:~# sh task.sh
root@piaware:~# crontab -e

Редактируем crontab в nano, вставив
* * * * * /root/task.sh >/dev/null 2>&1

Сохраняем файл нажав [Ctrl+O] и закрываем [Ctrl+X].
root@piaware:~# chmod 777 task.sh
root@piaware:~# reboot

После перезагрузки проверяем страницу со своей статистикой flightadsb.feeyo.com/user/rank
В четвертой колонке должна быть зеленая надпись online. А в списке Airport принятые борты (третья колонка — сколько секунд назад был принят сигнал от самолета).

На этом месте мой черновик «завис» на неопределенный срок, т.к. здесь я хотел написать как запустить на роутере с openwrt скрипт и ModeSMixer для раздачи данных на сервисы и таким образом выключить этот приемник и применить для других целей. Но у меня пока не предвидится свободного времени и я решил опубликовать как есть. Возможно кто-то захочет заказать бесплатный приемник и эта статья будет полезна.

ModeSMixer


Один приемник может раздавать данные на несколько сервисов и используется для этого программа ModeSMixer.

ModeSMixer — консольное приложение для объединения и ретрансляция потоков с данными Mode-S в различных форматах. Примерный вариант использования:


Программа предназначена для комбинирования и ретрансляции разных форматов потоков ModeS данных. Настроек по умолчанию программа не имеет. Всё задается параметрами.

Параметр --inConnect задает адреса и порты с которых поступают данные. А параметр --outServer определяет формат и порт для ретранслируемых данных. Пример на картинке будет выглядеть так:
./modesmixer2 --inConnect 192.168.0.105:30005 --inConnect 127.0.0.1:30005 --outServer sbs10001:10001  --outServer beast:31001 --globes 32000:tablename:home  --location XX.XXXXX:YY.YYYYY --web 8765  &

Параметр --location определяет широту и долготу места установки станции, и параметр --web определяет порт на котором будет работать вебинтерфейс программы. Подробнее о программе можно почитать здесь.

Настроив раздачу на несколько сервисов, владелец станции получает особое членство на каждом сервисе и доступ к непубличной информации и архиву полетов за определенный срок.

В случае использования PiAware данные уже отправляются на FlightAware и остается только забрать эти данные с помощью modesmixer2. И в случае Variflight необходимо получить данные в формате BaseStation на каком-то свободном порту, например, 10001. Параметр будет выглядеть так --outServer msg:10001. Если необходимо, то можно добавить порт 10002 для программы VirtualRadar: --outServer beast:10002
./modesmixer2 --inConnect localhost:30005 --inConnect localhost:30105 --outServer msg:10001  --outServer beast:10002 --location <широта>:<долгота> --web 8765  &

Чтобы это запускалось и перезапускалось автоматически необходимо отредактировать task.sh, добавив:

ps -eaf | grep modesmixer2 | grep -v grep
# if not found - equals to 1, start it
if [ $? -eq 1 ]
then
./modesmixer2 --inConnect localhost:30005 --inConnect localhost:30105 --outServer msg:10001  --location <широта>:<долгота> --web 8765  &
echo `date "+%G-%m-%d %H:%M:%S"`" modesmixer2            restart"
echo "------------------------------------------------------------------------"
else
echo `date "+%G-%m-%d %H:%M:%S"`" modesmixer2            running"
echo "------------------------------------------------------------------------"
fi

И наконец отредактируем скрипт get_message/send_message.py, указав новый порт с данными:
serverHost = 'localhost'
serverPort = 10001


А тем временем,


пока эта статья лежала в черновиках, из Китая появилась новость, касающаяся этих сервисов. В ноябре 2018 года китайские власти стали выключать ADSB-приёмники иностранных сервисов. Это можно увидеть в публичной статистике станций Flightaware на территории Китая:



Новость в том, что китайские энтузиасты радарспоттинга заявили, что им позвонили представители китайских властей и их посетила полиция, которые «очень красиво и вежливо» попросили их прекратить передачу данных ADS-B на заграничные сервисы, что, по-видимому, «ставит под угрозу национальную безопасность и суверенитет Китая».

Некоторые утверждали, что им позвонили, даже, если они не получили приемник от FlightRadar24 и FlightAware. Эти события вызвали переполох среди энтузиастов, и многие из них прекратили передачу данных ADS-B. Известно, что в FlightRadar24 попытались анонимизировать станции пользователей в Китае. Пока не ясно насколько это эффектно.

Уведомление китайских властей на английском языке:


«Ставит под угрозу национальную безопасность и суверенитет Китая» тот факт, что такие сервисы позволяют устанавливать местонахождение китайских (американских, европейских и прочих кроме стран бывшего СССР) военных самолетов. Для примера еженедельная траектория американского стратегического разведывательного БПЛА над международными водами на высоте 16 км:

image

В мире существует две системы вторичной радиолокации родом из США и СССР. Поэтому эти приемники и сервисы не могут показать местонахождение большинства «советских» самолетов, вертолетов, если они не оборудованы «американским» радиолокационным ответчиком, что необходимо только для полетов в воздушном пространстве, например, США или ЕС. Поэтому увидеть, что-то интересное на территории РФ можно в пограничных областях, желательно у моря. Например, упомянутый выше американский разведчик замечательно виден из Краснодара. Именно благодаря такому прибрежному размещению приемника, упомянутый выше, сервис PlaneRadar периодически попадает в новости российских СМИ.


P.S. VariFlight ADS-B запустил версию на английском языке — flightadsb.variflight.com
Tags:
Hubs:
Total votes 43: ↑43 and ↓0+43
Comments44

Articles