Смышлёные остановки Страница 1 из 7

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

Проект, о котором мы хотим рассказать получил у нас кодовое и немного смешное название «Смышлёные Остановки».




Итак, в чем суть – в городе «Н» есть городской транспорт на котором установлены системы слежения основанные на датчиках ГЛОНАСС, данные о перемещении стекаются в центральную диспетчерскую службу в виде постоянного потока сообщений от этих самых датчиков. Хочется разместить на остановке жидкокристаллическую панель, которая покажет, когда и какие транспортные средства, идущие по маршрутам прибудут.

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

Именно об этом мы и хотим сегодня рассказать, как от протокола общения с датчиками мы дошли до сборки железа для умной остановки и показали работающий прототип на выставке ТЕХНОПРОМ 2014.

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



Собираем данные в реальном времени

На данный момент нет единой системы или стандарта предоставления оперативных данных. В разных городах различные провайдеры, которые используют различные способы раздачи данных и различный формат и содержание. На данный момент мы столкнулись с двумя: передача данных по TCP и REST API на стороне провайдера.

Пример пакета, который мы получаем по TCP
<code>#D#00287;190614;034452;5628.0000;N;8457.8226;E;0;272;123;12;gosnum:3:379,num:3:3 тролл </code>

Пример пакета из REST API
<code>{ 	"online" : [ { 		"deviceHash" : 0558132541,  		"name" : "Автобус Х564ВЕ96",  		"timestamp" : 1384710565,  		"latitude" : 50.65,  		"longitude" : 60.56,  		"speed" : 43.5, 		"course" : 120.1,  		"sats" : 8,  		"route" : "021-bus" 	}, ... ] } </code>

Формат и содержание пакетов:
  • Идентификатор устройства.
  • Именование или идентификатор ТС – номер ТС и тип ТС.
  • Время снятия данных.
  • Широта и долгота.
  • Скорость.
  • Курс.
  • Количество спутников.
  • Идентификатор маршрута по которому движется ТС.
Все эти данные используются в работе алгоритма прогнозирования.
Рассмотрим оба варианта получения данных.

Функции и ответственность листнера:
  • Получение “сырых” данных от провайдера.
  • Парсинг данных и переработка в формат понимаемый системой. Из строки или из JSON в POJO.
  • Пересылка полученного POJO с данными в JMS в заранее определенный топик.
  • Отказоустойчивость. Для идентификации проблем в получении данных от провайдера или физической недоступности листнера, листнер должен отсылать ping пакеты в JMS.
  • Сохранение POJO после парсинга в отдельную базу данных. Сохранение сырых данных длинной в неделю. Данный механизм сделан для того, чтобы иметь возможность накопить минимальную статистику работы алгоритма. В процессе жизни системы предполагалась доработка и донастройка алгоритма, и, чтобы иметь возможность проверить изменения в алгоритме, мы сохраняем данные. И умеем их проигрывать для накопления статистики и оценки работы алгоритма после изменений.

В случае с TCP мы указываем хост и порт, и провайдер данных отсылает пакеты на этот хост. Далее в дело вступает наш листенер TCP канала.

Мы использовали в качестве основы для TCP листнера Netty. Он очень прост в использовании и стабилен в работе. В случае с REST API мы использовали клиента Jsoup, который опрашивает api по таймеру.

Сам листнер, это консольное приложение с возможностью указать хост, порт и настройки для JMS и базы данных.

Процесс работы листнера:
  • Получение данных по факту в случае с TCP или по таймеру в случае REST API.
  • Разбор строки или JSON и создание объекта класса NavigationPackage.
  • Отправка NavigationPackage в JMS.
  • Сохранение NavigationPackage в базу.
  • Отправка ping пакета в JMS (объект класса PingPackage).
  • 857
  • 24/06/2014


Поделись



Подпишись



Смотрите также

Новое