«Где мы, папа», — спросил меня 5-летний сын.
«Мы приземлимся примерно через час», — ответил я.
«Да нет, я имею в виду, где мы? Мы ещё не пролетаем Италию?»
Точно ответить я не мог. Это был недолгий перелёт по низкому тарифу без удобств в виде встроенных в подголовники кресел экранов. Тогда я огляделся по сторонам и заметил наклейку с призывом подключиться к WiFi-сети самолёта. Должно сработать. Думаю, что сайт вроде FlightRadar ответит на вопрос моего сынишки с точностью до нескольких метров.
Но, к его сожалению, я разработчик PySkyWiFi («абсолютно дурацкого WiFI-инструмента для бесплатного доступа в интернет при длительных перелётах»). Не платить за интернет авиакомпании — это моя личная фишка. Здесь же нам потребуется иная, офлайн-стратегия.
Я рассуждал так. Когда ты подключаешься к WiFi-сети самолёта, то обычно попадаешь на страницу оплаты, где покупаешь доступ в интернет. На этой же странице обычно предоставляется та же информация о полёте, что и на экранах подголовников — скорость, направление и расчётное время прибытия (Estimated Arrival Time, ETA). Поначалу я думал, что там будет ещё и карта.
В итоге я достал ноутбук, подключился к сети и загрузил платёжную страницу. На ней действительно показывалась воздушная скорость судна, направление полёта и расчётное время до прибытия. Но карты не было.
(Тогда я не додумался сделать скрин этой страницы, так что вот вам моя художественная интерпретация):
«Возможно, сервер, который отправляет нам эти данные, по факту отправляет и наше местоположение, но веб-страница этого не показывает», — подумал я. Открыв инструменты разработчика Chrome, я увидел, что мой браузер выполняет регулярные запросы к конечной точке
/info
.Я развернул один из этих запросов. Конечная точка
/info
действительно отправляла большие объёмы данных, включая поля для ground_speed
, wind_speed
и estimated_arrival_time
. В нижней части ответа я заметил поля для
latitude
и longitude
. Мой пульс участился. Но при внимательном рассмотрении оказалось, что они оба null
. Облом.Казалось, что на этом всё. Я уже собирался сдаться и сказать сыну, что мы летим где-то севернее Италии… над какой-то частью Европы. Но затем меня осенили две фантастических идеи.
Идея №1: конечная точка
/info
не сообщала наши координаты, но предоставляла точную и регулярно обновляемую информацию о скорости и направлении движения. Тогда в течение всего нашего обратного полёта я смогу отслеживать и сохранять эти данные примерно раз в секунду. Используя эту информацию, я буду определять, насколько далеко и в каком направлении мы ежесекундно перемещаемся. То есть смогу динамически вычислять наше местоположение, начав с координат аэропорта и поступательно их корректируя.Идея №2. Даже если бы я смог найти в ответе
/info
координаты нашей широты и долготы, ни мне, ни моему сыну они бы ничего полезного не сообщили. Однако я смог создать веб-приложение, которое выполняется на моём ноутбуке и в реальном времени показывает динамически вычисляемое местонахождение на карте. Это приложение может автоматически обновлять график расчётного времени прибытия, направления ветра, скорости, высоты и так далее. Ах да, ещё в нём есть интерфейс для выполнения произвольных запросов по этим данным и обратные вызовы событий, позволяющие программно активировать код, исходя из информации о полёте («когда ETA составит ровно 2 часа, программа будет блокировать мне доступ к Netflix.com и открывать последний черновик моего незаконченного романа»). Мой сын будет понимать, где он находится, а я проявлю себя как хороший папа.Я решил назвать приложение PyMyFlySpy, чтобы прослеживалась связь с PySkyWiFi. Мне не терпелось начать. К сожалению, в тот момент я был зажат между двумя детьми, 5-ти и 2-х лет, и мы все очень плохо разбирались в JavaScript. Оставалось с нетерпением ждать.
PyMyFlySpy
Наконец, мы приземлились. Я написал PyMyFlySpy за время праздников, посвятив этому поздние вечера и несколько послеобеденных часов, пока остальные члены семьи развлекались какими-то обыденными способами. Я не понимал, окажется ли дурным тоном использование ноутбука в традиционных итальянских кофейнях, и в каких из них есть WiFi, поэтому к своему бесконечному стыду нагуглил «starbucks рядом». Найдя подходящее заведение, я заказал себе моккачино и, усевшись в укромном уголке, принялся печатать.
В итоге я закончил PyMyFlySpy за день до нашего отлёта. Его код доступен на GitHub. Настроить и запустить это приложение несложно. В нём даже есть «холостой» режим, который позволяет симулировать полёт, не находясь в самолёте.
Что же конкретно умеет мой PyMyFlySpy?
▍ Карты и графики
PyMyFlySpy показывает карту с пройденным вами на данный момент путём. Он также показывает текущие метрики полёта и тренд их изменения за всё его время. Делает он это для всех данных, доступных с бортового WiFi, даже тех, которые на сайте или экране подголовника не отображаются. С его помощью вы можете точно видеть, где находитесь, и в некоторой степени ощущать себя пилотом.
▍ Интерфейс запросов
PyMyFlySpy сохраняет всю регистрируемую информацию в базе данных. В его UI есть страница, которая позволяет писать запросы к данным для определения, например «максимальной скорости за всё время полёта и момента её достижения» или «скорости ветра во время только что пройденной турбулентности».
Я не утверждаю, что это прям очень полезно, но, как минимум, просто круто.
▍ Поддержка нескольких авиалиний
У разных авиакомпаний разные системы WiFi. Регистратор для JetBlue не будет работать на авиалиниях AirFrance. К счастью, PyMyFlySpy позволяет с лёгкостью добавлять и использовать регистраторы для разных систем. Достаточно загрузить стартовую страницу подключения WiFi, открыть инструменты разработчика в браузере и найти способ спарсить данные с этой страницы, как сделал я выше. Затем нужно добавить новый код в конфигурацию PyMyFlySpy и указать на него регистратору. Всё остальное продолжит работать так же.
Проектирование системы
Система очень проста и состоит из 4 частей:
- Расширение Firefox — считывает данные полёта с сайта авиалинии и отправляет их на сервер PyMyFlySpy.
- Локальный сервер — сохраняет присылаемые расширением данные и делает их доступными для фронтенда.
- База данных SqLite — сохраняет всю эту информацию.
- Фронтенд — выводит данные, используя карты и графики.
В ходе разработки я принял одно неординарное решение — использовать для считывания данных полёта расширение Firefox вместо того, чтобы написать скрейпер, который бы напрямую выполнял собственные запросы. Такой скрейпинг информации получился бы более гибким и простым, да и полностью безвредным. Сотни людей и так подключены к WiFi, а базовая страница бортовой WiFi-системы связывается с конечной точкой
/info
каждые пару секунд. Добавление дополнительного запроса от скрейпера никак бы не навредило.Тем не менее авиакомпания вряд ли приветствовала бы вмешательство в свои бортовые сервисы посторонних, даже если совершающие его люди очень осторожны, доброжелательны и благородны. И чтобы их не тревожить, я придумал ещё более рациональный подход.
Вместо скрейпинга конечной точки данных я написал расширение для Firefox. Это расширение ожидает, когда базовая страница WiFi-системы запросит последние данные с
/info
. После запроса она просматривает полученные данные и отправляет их на сервер PyMyFlySpy, который записывает эти данные в БД для передачи фронтенду. Подобное использование расширения означает, что PyMyFlySpy никогда не взаимодействует с информацией сервера самолёта напрямую и навредить этому серверу никак не может. Мне пришлось написать расширение для Firefox, а не Chrome, потому что в Chrome планируют урезать возможность взаимодействия расширений с запросами сайта (вроде тех, которые совершаются к конечной точке
/info
). В частности, разработчики этого браузера планируют запретить расширениям считывать ответы на HTTP-запросы сайта, а значит, PyMyFlySky не сможет считывать данные, возвращаемые /info
. Насколько я понимаю, эти ограничения частично вызваны заботой о безопасности, а отчасти служат для усложнения разработки блокировщиков рекламы. Как бы то ни было, но PyMyFlySpy требует Firefox. Дальнейшие планы — подписка на события
PyMyFlySpy даёт нам программный доступ к данным о полёте. И будет здорово использовать их для активации различных событий вроде таких:
- «В течение первой половины полёта позволять мне открывать только большой отчёт, который нужно закончить к 17:00».
- «Когда мы окажемся в радиусе 10 миль от Великого Каньона, отправить детям сообщение в Slack с призывом выглянуть в иллюминатор. Также отправить сообщение Slack и мне, чтобы я сам им об этом сказал.»
- «Если высота начнёт падать со скоростью больше 300 футов/секунду, воспроизводить на всех моих устройствах спокойный, но очень назойливый звук ».
Пожалуй, займусь этим в следующие праздники.
Полёт домой
Обратный перелёт был вечерним. Мы взобрались на борт и взлетели. Я достал ноутбук, подключился к WiFi, загрузил PyMyFlySpy и повернулся к сыну, чтобы показать, где мы находимся. Я показывал ему прототип программы всю прошлую неделю, и его реакция была где-то между «безразличием» и «лёгким интересом». Но он уже уснул. Тогда я сделал несколько скриншотов, чтобы показать их ему позже.
Следующие несколько часов я провёл за мониторингом и отладкой регистратора, чтобы обеспечить его устойчивую работу. Мой двухлетний сын кричал на протяжении всего полёта, то и дело норовя вывалиться на пол. Я поддерживающим взглядом посматривал на жену, которая сидела с ним через проход от меня, и давал понять, что готов его взять. Но супруга мотала головой — она понимала, что у меня важное дело.
Я просматривал графики. Температура была в норме, воздушная скорость стабильна, и тут внезапно высота упала на пятьдесят футов. Мне пришла мысль сообщить об этом пилотам, но я решил, что у них наверняка всё под контролем. Хотя наблюдение всё же продолжил — мало ли.
Telegram-канал со скидками, розыгрышами призов и новостями IT ?
Комментарии (14)
vindy
15.12.2024 09:13Ну прикольно, но оба проекта скорее штука для собственного развлечения, чем для оптимального решения проблемы. Гугл мэпс на телефоне расположенном у иллюминатора отлично покажет местоположение.
Другой проект по бесплатному интернету через туннель в личном кабинете авиакомпании - тоже такое себе. Проигрывает по универсальности туннелю через DNS, который будет работать везде.
Kianu
15.12.2024 09:13А можно более подробно про dns тоннель? Или это общая концепция и реализаций масса идти и просто гуглить?
Squoworode
15.12.2024 09:13Думаю, что сайт вроде FlightRadar ответит на вопрос моего сынишки с точностью до нескольких метров.
Но, к его сожалению, я разработчик PySkyWiFi («абсолютно дурацкого WiFI-инструмента для бесплатного доступа в интернет при длительных перелётах»).
То есть у него уже есть инструмент, чтобы открыть FlightRadar прямо сейчас, но вместо этого он напишет ещё один инструмент завтра, когда задача будет уже неактуальна...
orbion
15.12.2024 09:13Если не нужна большая точность, можно с помощью акселерометра и гироскопа в телефоне определять местоположение. Но для этого нужен трекинг пути с самого начала полёта и задание начальных координат.
Wijey
если сидеть у окна - телефон с оффлайн-картами с трудом, но зацепится к спутникам и покажет положение и скорость
vindy
Да даже и без специального скачивания оффлайн карт, в Гугл мэпс карта мира с приемлемой степенью детализации есть по дефолту. Издревле так трекаю свое местоположение во время полета, согласен с вами в том, что статья решает проблему каким то неоптимальным способом.
shark14
В последние годы при полете над территорией РФ текущая локация GPS телефоном не показывается (локация просто фризится в последней известной точке), при этом, скажем, над Турцией — показывается.
Возможно, это как-то связано с санкциями.
legioner
Не далее чем в середине октября летел по маршруту AER-SSH. На подлете к Кипру локация GPS зафризилась в ~700км от реального местоположения на высоте ~1км где-то в пустыни Иордании. И держалась почти до самой посадки. Сигнал от "спутников" был стабилен.
KohINoor
В это время активно спуфился GPS над Израилем. Жители показывались либо в аэропорту Иордании, либо Ливана. Может и до Кипра добивало где-то?
YourgenAP
Израильские глушилки с хорошим запасом покрывают весь южный Кипр, если не вообще весь остров. Давняя проблема для навигации по спутникам в восточной части Средиземного моря. Этот регион всегда стоит в списке регионов с глушением сигнала. По какой-то причине все самолеты в этом регионе действительно отбиваются по координатам в аэропорту Аммана.
YourgenAP
Не санкции, а глушилки в зоне боевых действий. РЭБ, борьба с дронами и все из этой серии. Над центральноевропейской частью России последние 2.5 года летают без GPS
vindy
Я простой эникей, мне искренне интересно. Можно что-ли спуфить приемники на определенной высоте и не спуфить наземные? Яндекс такси и тд совершенно точно не во всей европейской части России сломано
YourgenAP
Ну, глушить на определенной высоте и не спуфить наземные вряд ли. Единственное, что мне приходит в голову, это то, что Яндекс Такси и прочее работает на чистом Глонассе, который работает на частотной модуляции, так что его сложнее заглушить.