«Где мы, папа», — спросил меня 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 частей:

  1. Расширение Firefox — считывает данные полёта с сайта авиалинии и отправляет их на сервер PyMyFlySpy.
  2. Локальный сервер — сохраняет присылаемые расширением данные и делает их доступными для фронтенда.
  3. База данных SqLite — сохраняет всю эту информацию.
  4. Фронтенд — выводит данные, используя карты и графики.


В ходе разработки я принял одно неординарное решение — использовать для считывания данных полёта расширение 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)


  1. Wijey
    15.12.2024 09:13

    если сидеть у окна - телефон с оффлайн-картами с трудом, но зацепится к спутникам и покажет положение и скорость


    1. vindy
      15.12.2024 09:13

      Да даже и без специального скачивания оффлайн карт, в Гугл мэпс карта мира с приемлемой степенью детализации есть по дефолту. Издревле так трекаю свое местоположение во время полета, согласен с вами в том, что статья решает проблему каким то неоптимальным способом.


      1. shark14
        15.12.2024 09:13

        В последние годы при полете над территорией РФ текущая локация GPS телефоном не показывается (локация просто фризится в последней известной точке), при этом, скажем, над Турцией — показывается.

        Возможно, это как-то связано с санкциями.


        1. legioner
          15.12.2024 09:13

          Не далее чем в середине октября летел по маршруту AER-SSH. На подлете к Кипру локация GPS зафризилась в ~700км от реального местоположения на высоте ~1км где-то в пустыни Иордании. И держалась почти до самой посадки. Сигнал от "спутников" был стабилен.


          1. KohINoor
            15.12.2024 09:13

            В это время активно спуфился GPS над Израилем. Жители показывались либо в аэропорту Иордании, либо Ливана. Может и до Кипра добивало где-то?


            1. YourgenAP
              15.12.2024 09:13

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


        1. YourgenAP
          15.12.2024 09:13

          Не санкции, а глушилки в зоне боевых действий. РЭБ, борьба с дронами и все из этой серии. Над центральноевропейской частью России последние 2.5 года летают без GPS


          1. vindy
            15.12.2024 09:13

            Я простой эникей, мне искренне интересно. Можно что-ли спуфить приемники на определенной высоте и не спуфить наземные? Яндекс такси и тд совершенно точно не во всей европейской части России сломано


            1. YourgenAP
              15.12.2024 09:13

              Ну, глушить на определенной высоте и не спуфить наземные вряд ли. Единственное, что мне приходит в голову, это то, что Яндекс Такси и прочее работает на чистом Глонассе, который работает на частотной модуляции, так что его сложнее заглушить.


  1. vindy
    15.12.2024 09:13

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

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


    1. Kianu
      15.12.2024 09:13

      А можно более подробно про dns тоннель? Или это общая концепция и реализаций масса идти и просто гуглить?


  1. Squoworode
    15.12.2024 09:13

    Думаю, что сайт вроде FlightRadar ответит на вопрос моего сынишки с точностью до нескольких метров.

    Но, к его сожалению, я разработчик PySkyWiFi («абсолютно дурацкого WiFI-инструмента для бесплатного доступа в интернет при длительных перелётах»).

    То есть у него уже есть инструмент, чтобы открыть FlightRadar прямо сейчас, но вместо этого он напишет ещё один инструмент завтра, когда задача будет уже неактуальна...


    1. blind_oracle
      15.12.2024 09:13

      Как говорят немцы - Der Weg ist Das Ziel :)


  1. orbion
    15.12.2024 09:13

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