Hospitality / IoT

TV-PORTAL / Damba Relax — Wi-Fi и ТВ-киоск

TV-PORTAL — собственный продакшн-проект для гостевого дома Damba Relax в Янтарном Калининградской области. Гость подтверждает доступ к Wi-Fi звонком, а с телевизора в номере заказывает завтрак, сауну, экскурсии, самокаты, мангал и другие услуги.

Обсудить похожий проект
Цифровая система гостевого дома Damba Relax с Wi-Fi, ТВ-киоском и панелью персонала

Задача

Объединить гостевой Wi-Fi, сервисы в номере, оплату, управление персонала и голосовые сценарии в одной надёжной системе.

Решение

Как реализовали проект

Единый Flask-сервис обслуживает гостевой портал, ТВ-интерфейсы всех номеров и административную панель. Он связывает проверку через sms.ru, авторизацию устройств в UniFi, оплату по СБП через ЮKassa, уведомления в Telegram, Home Assistant, Алису и управление Android TV по ADB.

Состав работ

Что вошло в решение

  • 01Гостевой Wi-Fi без пароля с проверкой звонком
  • 02ТВ-киоск с заказом и оплатой услуг из номера
  • 03Единая панель гостей, бронирований, контента и заказов
  • 04Оплата по СБП с автоматической сверкой статуса
  • 05Голосовой запуск портала через Алису
  • 06Мультиномерная архитектура с отдельными темами

Инфраструктура

Архитектура решения

  1. 01

    Один Flask-процесс обслуживает все номера по маршрутам /tv/room-<id>/...

  2. 02

    SQLite хранит гостей, бронирования, заказы, платежи и контент

  3. 03

    Занятость номеров вычисляется по пересечениям бронирований без плотной календарной таблицы

  4. 04

    Фоновый worker сверяет исходящие запросы к ЮKassa без зависимости от входящего webhook

  5. 05

    Caddy выпускает сертификаты через Cloudflare DNS-01 и разделяет гостевой и локальный ТВ-доступ

  6. 06

    Сервис работает в Debian 12 LXC на Proxmox и управляется через systemd

Возможности

Функционал

01

Подтверждение гостя звонком

Портал запускает серверную проверку номера через sms.ru. Процесс продолжается даже после закрытия captive-браузера iOS при переходе в приложение телефона.

02

Доступ к Wi-Fi через UniFi

После успешной проверки сервис находит устройство по MAC-адресу и выдаёт ему доступ через UniFi API без общего пароля для гостей.

03

Заказ услуг с телевизора

Крупный интерфейс ТВ-киоска позволяет заказать завтрак, сауну, экскурсию, самокаты, мангал и дополнительные услуги прямо из номера.

04

Оплата по СБП

ЮKassa формирует QR-код, а фоновая сверка подтверждает фактический статус платежа. Заказ не становится оплаченным без ответа платёжной системы.

05

Панель персонала

Сотрудники управляют гостями, бронированиями, номерами, контентом и заказами в одном интерфейсе и получают оперативные уведомления.

06

Голосовые сценарии

Команда Алисе запускает сценарий Home Assistant: телевизор просыпается, а ADB открывает страницу портала конкретного номера.

07

Управление несколькими номерами

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

08

Уведомления и контроль состояния

Telegram Bot API сообщает персоналу о событиях, а endpoint /health используется для мониторинга доступности сервиса.

Стек проекта

Технологии

Flask
Python
SQLite
JavaScript
Android
Kotlin
Home Assistant
UniFi
Telegram
Caddy
Cloudflare

Защита данных

Безопасность

  • Параметризованные SQL-запросы и ручные транзакции при миграциях
  • HMAC-сессия администратора и отдельный X-Admin-Key для API
  • X-Frame-Options: DENY и no-store для административных страниц
  • Проверка IP ЮKassa и Idempotence-Key для платёжных операций
  • Резервная копия приложения и рабочей SQLite-базы перед рискованным деплоем

Живые данные

Интеграции

sms.ru — проверка гостя по звонкуUniFi Network — авторизация устройства по MACЮKassa — СБП, QR-коды и сверка платежейTelegram Bot API — уведомления персоналаHome Assistant и Алиса — голосовые сценарииAndroid TV и ADB — запуск киоска в номереCaddy и Cloudflare — HTTPS и маршрутизация

UX / UI

Дизайн-процесс

Интерфейс проектировался прежде всего для телевизора: крупные зоны нажатия, короткие сценарии, высокая контрастность и отдельная тема каждого номера. Панель персонала отделена от гостевого контура, а содержимое услуг меняется централизованно.

Инженерная работа

Нетривиальные решения

Платежи без публичного webhook

Сервис не открыт входящим трафиком из интернета, поэтому статус платежа подтверждает исходящий reconcile-worker. Webhook оставлен как будущее улучшение, но не является точкой отказа.

Проверка после закрытия captive-браузера

iOS закрывает captive-окно при переходе по tel:. Проверку перенесли в серверный worker, который завершает сценарий независимо от состояния браузера.

Несколько номеров в одном процессе

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

Голосовое управление телевизором

Home Assistant принимает триггер Алисы и через ADB будит нужный Android TV, после чего открывает персональный адрес комнаты.

Безопасные миграции живой базы

Миграции сначала прогоняются на копии продакшн-базы. Так была обнаружена зависимость SELECT * от физического порядка колонок и устранена до выкладки.

Честные границы продакшна

Текущий браузерный киоск работает в продакшне. Нативный Kotlin-клиент ещё развивается, а переход с Flask dev server на production WSGI зафиксирован как следующий инфраструктурный этап.

Результат

Система работает в реальном гостевом доме: выдаёт доступ к Wi-Fi, принимает заказы и оплату, уведомляет персонал и управляет ТВ-сценариями. Нативный клиент для Android TV развивается отдельно; текущая продакшн-версия использует браузерный киоск и ADB.

Следующий кейс

Damba — сетевая безопасность и DevOps

Смотреть кейс →