КЕЙС

FIDS на SpinetiX: как устроен проект в аэропорту Уфы

Разбор для интеграторов: фид Dld/Dla, пайплайн виджета на jSignage, статусы из 5 полей, словарь 1500+ локаций, RPC по LAN — вся обработка на плеере, без сервера.

FIDS на SpinetiX: как устроен проект в аэропорту Уфы

Разбор для интеграторов: как в аэропорту Уфы FIDS собран на трех плеерах SpinetiX EMP-III без выделенного сервера обработки. Аэропорт отдает неполные данные — статусы, логотипы и английский плеер достраивает сам, скриптами внутри виджета на jSignage.

Ниже — структура источника, пайплайн обработки, управление по RPC и зоны ответственности. Задача реализована совместно с интегратором Future Vision (ООО «Компэлс Интеграция»); SpinetiX закрыл плееры, контент под ключ и обучение.

2 источника: Dla.txt (вылеты) + Dld.txt (прилеты)
316 строк в тестовом фиде
5 параметров → 1 статус
1500+ записей в словаре RU→EN
окно ±2 часа, обновление раз в минуту
0 серверов обработки

Что было в ТЗ — и что пришло в проде

На пресейле тестовый проект собирали на JSON, доступном по HTTP-адресу. Ближе к запуску источник и структура изменились: данные ушли в закрытый контур, разъехались по двум файлам и потеряли часть полей. Классический FIDS на сервере такое переживает переписыванием backend. Здесь вся адаптация — в виджете на плеере.

Тест (пресейл)

JSON по HTTP из внешнего источника

Вылеты и прилеты в одном источнике

Готовая англоязычная версия

Статусы и логотипы уже в данных

Доступ к данным откуда угодно

Реальность (прод)

Текстовый файл (CSV) внутри закрытой LAN

Dla.txt (вылеты) и Dld.txt (прилеты) раздельно

Только русский — EN достраиваем сами

Ни статусов, ни логотипов в фиде

Только локальная сеть, без интернета

Источник данных: структура фида

Информационная система аэропорта выгружает расписание в локальную сеть двумя текстовыми файлами: Dla.txt (отправление) и Dld.txt (прибытие). Виджет нацелен на файл по URI, обработчик — CSV, обновление данных — при цикле показа, раз в минуту. В тестовом фиде — 316 строк.

Строка — это «сырая» запись рейса. Изображений, статусов и английского в ней нет; есть служебные поля, часть из которых нужно распарсить:

  • aircompany — код перевозчика (по нему подбирается логотип)
  • flight — номер рейса со служебным хвостом, например «363%SEC=TK~9048»: все, что после знака «%», отсекается
  • location — город на русском (МОСКВА ШЕРЕМЕТЬЕВО, АНТАЛЬЯ), переводится словарем
  • time_plan / time_fact — плановое и фактическое время; их сравнение дает признак изменения
  • terminal (T1/T2), gate, desk — терминал, выход, стойка регистрации
  • registration, cancel — служебные флаги; вместе с временем формируют статус
Тест источника данных в Elementi: CSV-парсер, 316 строк, поля aircompany/flight/location/terminal
Тест источника данных в Elementi: CSV-парсер, 316 строк, поля aircompany/flight/location/terminal

Обработка на плеере: пайплайн виджета

Виджеты «Табло прибытия» и «Табло отправления» написаны на jSignage — библиотеке SpinetiX, по духу близкой к jQuery. Массив строк обрабатывается прямо в коде виджета: функция строит две страницы — русскую и английскую — из одного набора данных, прогоняя каждую запись через общий обработчик processItem(item, locale).

  • parseDate(time_plan / time_fact) — приводит время к сравнимому виду
  • getTimeChanged(plan, fact) — отмечает расхождение планового и фактического времени
  • getStatus(item, locale, statusColors, statusDictionary, type) — из пяти служебных полей выводит статус и его цвет (отменен → красный, посадка → зеленый)
  • getLogo(item, logoPaths) — подбирает логотип по коду перевозчика, с запасным alt.png
  • getLocation(item, locale, locationDictionary) — переводит город по словарю (1500+ записей)
  • getFlight(text) — берет часть номера рейса до знака «%», отсекая служебный хвост
  • formatDate + фильтр ±2 часа — финальное форматирование и отсев неактуальных рейсов

Ключевая деталь для интегратора: логика вынесена в конфиг-объект service (statusColors, statusDictionary, logoPaths, locationDictionary, type). Под новый объект — другой аэропорт, другой набор статусов, свой набор логотипов — движок переиспользуется без переписывания парсера.

Код виджета modifyData.js: processItem, getStatus, getLogo, getLocation, getFlight
Код виджета modifyData.js: processItem, getStatus, getLogo, getLocation, getFlight

Библиотека логотипов и словарь локаций

Аэропорт не передает графику, поэтому логотипы живут в самом проекте: свыше сотни PNG по авиакомпаниям (aeroflot.png, pobeda.png, azimuth.png, utair.png…) плюс alt.png — запасная иконка, если код перевозчика не распознан. В шаблоне за подстановку отвечает токен [[logo]], за перевод города — токен [[location]], который тянет значение из словаря на 1500+ локаций RU→EN.

Библиотека логотипов авиакомпаний в проекте Elementi
Библиотека логотипов авиакомпаний в проекте Elementi

Обработка ошибок: папка «broken data test»

Реальный фид рано или поздно отдаст битую или неполную строку. В проекте есть отдельная папка broken data test и вкладка «Обработка ошибок» в настройках источника: виджет проверяется на некорректных данных и не падает — пропускает проблемную запись, а не гасит все табло. Для объекта, который работает 24/7, это не украшение, а требование.

Управление: RPC по LAN вместо сервера приложений

Переключением показов управляет виджет «Интерактивный плейлист» и адаптивная HTML-панель — она открывается на ПК, планшете или смартфоне внутри локальной сети. Нажатие кнопки отправляет RPC-команду по LAN прямо на плеер: три режима (табло вылетов + реклама, табло прилетов + реклама, полноэкранная реклама) переключаются мгновенно.

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

Режим табло вылетов с рекламным блоком в проекте Elementi
Режим табло вылетов с рекламным блоком в проекте Elementi

Почему это выигрывает у FIDS на ПК и сервере

Классический FIDS — это Windows-сервер обработки плюс тонкие клиенты на экранах. Три слабых места: единая точка отказа (упал сервер — встали все табло), зависимость от ОС и обновлений, и открытый сетевой периметр. У SpinetiX обработка живет на самом плеере под DSOS на базе Linux; сервера обработки нет, каждый экран автономен, контур закрыт.

Синий экран смерти на табло аэропорта в день сбоя CrowdStrike
Синий экран смерти на табло аэропорта в день сбоя CrowdStrike

Где здесь маржа интегратора

В классическом FIDS большую часть чека забирают лицензии вендора — серверный софт и плата за каждый экран. У SpinetiX этой статьи нет: плеер EMP-III на экран и разовая лицензия Elementi. Деньги, которые раньше уходили вендору, остаются в вашем проекте — вы продаете экспертизу и работу по автоматизации, а не перепродаете чужой софт. Никакого vendor-lock: дорабатывать и переиспользовать проект может любой интегратор, знающий Elementi и jSignage.

Что dstools берет на себя на пресейле

Интегратор закрывает экраны, монтаж и ввод в эксплуатацию. На стороне dstools — весь контентный и программный слой под ключ: аналитика и проверка данных заказчика, формулирование ТЗ, дизайн макета, программирование виджетов, контент-менеджмент (перевод, поиск и обработка логотипов, приведение данных к единому формату), сборка проекта в Elementi, тестирование сценариев, методичка для сотрудников и первичная поддержка после запуска.

123CMS.app — слой регулярной выручки

Разовый проект можно превратить в регулярную выручку: 123CMS.app добавляет заказчику брендированную консоль управления сетью экранов поверх плееров SpinetiX — с ролями, расписаниями и модулями (реклама, навигация, proof-of-play). Для интегратора это recurring-подписка и повод возвращаться к клиенту, а не разовая поставка железа.

Технический состав

Заказчик
АО «Международный аэропорт «Уфа» им. Мустая Карима
Интегратор
Future Vision (ООО «Компэлс Интеграция»)
Экраны
3 × LED 1920×1200 (1 фасадный, 2 внутренних)
Плееры
3 × SpinetiX EMP-III, лицензия SYSTEMS
Софт
Elementi; виджеты на jSignage
Источник
Dla.txt (вылеты) + Dld.txt (прилеты), CSV по LAN
Обновление
раз в минуту, окно ±2 часа
Обработка
парсинг и достройка полей в коде виджета, конфиг service
Управление
виджет «Интерактивный плейлист» + HTML-панель, RPC по LAN
Публикация
WebDAV из Elementi
Контур
закрытая сеть без интернета, 24/7
Структура проекта Elementi: backgrounds, fonts, headers, interface, logos, widgets, broken data test
Структура проекта Elementi: backgrounds, fonts, headers, interface, logos, widgets, broken data test

Частые вопросы интегратора

Нужен ли выделенный сервер обработки данных?
Нет. Парсинг, формирование статусов, подстановка логотипов и перевод выполняются в коде виджета прямо на плеере EMP-III. Сервер приложений между источником и экраном отсутствует.
Что если аэропорт поменяет структуру данных?
Логика вынесена в конфиг-объект service (словари статусов и локаций, пути к логотипам, тип табло), поэтому многое настраивается без правки парсера. Смена самого формата/структуры фида по ТЗ — это отдельная разработка: «Изменение структуры и формата данных расцениваются как новая разработка».
На чем пишутся виджеты?
На jSignage — JS-библиотеке SpinetiX, близкой по логике к jQuery. Проект — это index.svg с макетом, папка js со скриптами и виджеты, которые нацелены на файлы данных Dla.txt / Dld.txt.
Как переиспользовать решение на другом объекте?
Заменить конфиг service (свои статусы и цвета), библиотеку логотипов и словарь локаций, нацелить виджет на новый источник. Движок парсинга и раскладка остаются теми же — это и дает скорость на следующем проекте.
Как масштабируется управление сетью экранов?
Локально — HTML-панель и RPC по LAN. Для сети объектов и регулярной выручки сверху ставится 123CMS.app: брендированная консоль с ролями, расписаниями и модулями.
Оборудование и сценарии
Следующий шаг

Посчитаем похожий проект для вас

Опишите задачу — подберем оборудование, покажем аналогичные внедрения, посчитаем смету. Без маркетинговых заходов.