Розробка мобільного застосунку для BMS-керування будівлею

BMS-проєкти починаються однаково: замовник показує схему будівлі з контролерами Siemens Desigo CC, Schneider Electric EcoStruxure або Johnson Controls Metasys і каже «хочемо бачити все це в телефоні». За цим «все це» ховаються десятки протоколів, polling-цикли від 1 секунди до 15 хвилин, історична б

Розробка та підтримка будь-яких видів мобільних додатків:

Інформаційні та розважальні мобільні програми
Новинки, ігри, довідники, онлайн-каталоги, погодні, фітнес та здоров'я, туристичні, освітні, соціальні мережі та месенджери, квіз, блоги та подкасти, форуми, агрегатори
Мобільні програми електронної комерції
Інтернет-магазини, B2B-додатки, маркетплейси, онлайн-обмінники, кешбек-сервіси, біржі, дропшиппінг-платформи, програми лояльності, доставка їжі та товарів, платіжні системи
Мобільні програми для управління бізнес-процесами
CRM-системи, ERP-системи, управління проектами, інструменти для команди продажів, облік фінансів, управління виробництвом, логістика та доставка, управління персоналом, системи моніторингу даних
Мобільні програми електронних послуг
Дошки оголошень, онлайн-школи, онлайн-кінотеатри, платформи надання електронних послуг, платформи кешбеку, відеохостинги, тематичні портали, платформи онлайн-бронювання та запису, платформи онлайн-торгівлі

Це лише деякі з типів мобільних додатків, з якими ми працюємо, і кожен із них може мати свої специфічні особливості та функціональність, а також бути адаптованим під конкретні потреби та цілі клієнта.

Послуги, які ми пропонуємо
Показано 1 з 1Усі 1734 послуг
Розробка мобільного застосунку для BMS-керування будівлею
Складний
від 2 тижнів до 3 місяців

Наші компетенції:

Часті запитання

Останні роботи

  • image_mobile-applications_feedme_467_0.webp
    Розробка мобільного додатка для компанії FEEDME
    897
  • image_mobile-applications_xoomer_471_0.webp
    Розробка мобільного додатку для компанії XOOMER
    784
  • image_mobile-applications_rhl_428_0.webp
    Розробка мобільного додатку для компанії RHL
    1218
  • image_mobile-applications_zippy_411_0.webp
    Розробка мобільного додатку для компанії ZIPPY
    1081
  • image_mobile-applications_affhome_429_0.webp
    Розробка мобільного додатку для компанії Affhome
    1004
  • image_mobile-applications_flavors_409_0.webp
    Розробка мобільного додатку для компанії FLAVORS
    600

BMS-проєкти починаються однаково: замовник показує схему будівлі з контролерами Siemens Desigo CC, Schneider Electric EcoStruxure або Johnson Controls Metasys і каже «хочемо бачити все це в телефоні». За цим «все це» ховаються десятки протоколів, polling-цикли від 1 секунди до 15 хвилин, історична база на роки назад та вимога працювати навіть коли основний сервер BMS перезавантажується. Ми беремо такі проєкти під ключ: від аналізу протоколів до публікації в stores. Наш досвід — 10+ років у BMS-інтеграції та понад 50 реалізованих об'єктів. Оцінюємо проєкт за 2 дні та гарантуємо стабільну роботу при будь-якому навантаженні.

Протоколи та шлюзи

Промислові BMS говорять на BACnet/IP, Modbus TCP/RTU, KNX/IP та LonWorks. Напряму з мобільного застосунку до них не ходять — між контролерами та REST/WebSocket API стоїть шлюз або middleware.

Типовий стек інтеграції:

Рівень Технологія
Контролери BACnet/IP, Modbus TCP, KNX
Шлюз Node-RED, Niagara Framework 4, власний Python/Go сервіс
Transport MQTT over TLS, REST, WebSocket
Мобільний клієнт Flutter / Swift / Kotlin

Niagara Framework 4 (Tridium) — де-факто стандарт для великих об'єктів. Він вміє нормалізувати BACnet-об'єкти в єдиний REST API (/haystack/api/read?filter=bacnet) та віддавати WebSocket-стрим змін. Робота з Haystack API через Dart:

class HaystackClient { final Dio _dio; final String _baseUrl; HaystackClient(this._baseUrl, String username, String password) : _dio = Dio(BaseOptions( baseUrl: _baseUrl, headers: { 'Authorization': 'Basic ${base64Encode(utf8.encode('$username:$password'))}', 'Accept': 'application/json', }, )); Future<List<HaystackRow>> read(String filter) async { final response = await _dio.get('/haystack/api/read', queryParameters: {'filter': filter}); final grid = HaystackGrid.fromJson(response.data); return grid.rows; } Future<Map<String, dynamic>> readPoint(String pointId) async { final response = await _dio.get('/haystack/api/hisRead', queryParameters: { 'id': '@$pointId', 'range': 'today', }); return response.data; } } 

Для об'єктів з MQTT-шлюзом (Node-RED конвертує BACnet → MQTT JSON) використовуємо mqtt_client у Flutter. Топіки організовуємо за ієрархією будівлі: building/{buildingId}/floor/{floor}/zone/{zone}/{parameter}.

Як ми інтегруємося з існуючою BMS?

Процес завжди починаємо з аудиту контролерів: з'ясовуємо, які протоколи використовуються, яка версія Niagara або іншого middleware, чи є вже REST/WebSocket API або потрібна установка шлюзу. Потім проєктуємо схему потоків даних: які точки читаємо, які пишемо, з якою періодичністю. Сертифіковані інженери налаштовують шлюз та проводять інтеграційне тестування. Результат — єдиний інтерфейс на телефоні замість кількох панелей керування.

Архітектура даних реального часу: чому DataHub критичний?

Найскладніший момент у BMS-застосунку — не підключення, а керування потоком даних. Температура в 200 зонах оновлюється кожні 30 секунд, освітлення — за подією, енергоспоживання — щохвилини. Все це не можна перепідписувати при кожному перемальовуванні UI.

Рішення — централізований DataHub на рівні застосунку:

class BmsDataHub { final MqttClient _mqtt; final _streams = <String, BehaviorSubject<BmsPoint>>{}; Stream<BmsPoint> watchPoint(String pointId) { if (!_streams.containsKey(pointId)) { _streams[pointId] = BehaviorSubject(); _mqtt.subscribe('building/+/+/+/$pointId', MqttQos.atLeastOnce); } return _streams[pointId]!.stream; } void _onMessage(List<MqttReceivedMessage<MqttMessage>> events) { for (final event in events) { final topic = event.topic; final payload = MqttPublishPayload.bytesToStringAsString( (event.payload as MqttPublishMessage).payload.message); final point = BmsPoint.fromJson(jsonDecode(payload)); _streams[point.id]?.add(point); } } } 

BehaviorSubject з пакету rxdart зберігає останнє значення — віджет, який підписався після приходу даних, одразу отримує актуальний стан без очікування наступного циклу polling.

Інтерактивний план поверху

Замовники завжди хочуть план будівлі з живими даними. DXF або SVG-план конвертуємо в SVG (через ODA File Converter для DXF), рендеримо через flutter_svg + InteractiveViewer. Точки датчиків — overlay поверх SVG з позиціонуванням за нормалізованими координатами:

class FloorPlanWidget extends StatelessWidget { final FloorPlan plan; final Map<String, BmsPoint> liveData; @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { return Stack(children: [ SvgPicture.asset('assets/floors/${plan.id}.svg', width: constraints.maxWidth), ...plan.sensors.map((sensor) => Positioned( left: sensor.x * constraints.maxWidth, top: sensor.y * constraints.maxHeight, child: SensorMarker( point: liveData[sensor.pointId], type: sensor.type, ), )), ]); }); } } 

Маркери змінюють колір за порогами: зелений (норма), жовтий (попередження), червоний (аварія). Пороги беремо з BMS-конфігурації, не хардкодимо.

Керування: запис значень у BACnet-точки

Читати простіше, ніж писати. Для командування BACnet-точками (setpoint температури, увімкнення/вимкнення освітлення) через REST-шлюз:

Future<void> writePoint(String pointId, dynamic value) async { // Оптимістичне оновлення UI _hub.updateLocally(pointId, value); try { await _api.put('/haystack/api/pointWrite', data: { 'id': '@$pointId', 'level': 8, // пріоритет запису BACnet (1-16, нижче = вищий пріоритет) 'val': value, 'who': _authService.currentUser, 'duration': 'PT0S', // permanent }); } on DioException catch (e) { // Відкат при помилці _hub.revertLocally(pointId); rethrow; } } 

BACnet Priority Array — деталь, яку ігнорують і потім не можуть зрозуміти, чому уставка температури не змінюється: контролер приймає команди, але вони перебиваються вищим пріоритетом з BMS-розкладу (рівень 2-4). Рівень 8 — стандартний для ручного оператора.

Алери та журнал подій

Аварійні події з BMS надходять через MQTT або WebSocket. Локальні push-сповіщення генеруємо через flutter_local_notifications, серверні push (коли застосунок закритий) — через FCM з високим пріоритетом (priority: high, content_available: true).

Журнал подій: SQLite через drift для офлайн-зберігання 30 днів історії, посторінкове завантаження з API для старіших записів.

Розмежування прав

У реальних об'єктах різні користувачі бачать різні поверхи та зони. Права зберігаються на бекенді, мобільний клієнт запитує список доступних об'єктів при логіні та не будує маршрути до недоступних ресурсів. Спроба записати в заборонену точку → HTTP 403 → локальний відкат + сповіщення користувачеві.

Що входить у розробку?

  • Аналіз протоколів контролерів та архітектури BMS.
  • Проєктування схеми інтеграції та потоків даних.
  • Реалізація мобільного клієнта (iOS/Android на Flutter або нативному стеку).
  • Налаштування шлюзу та інтеграційне тестування.
  • Публікація в App Store та Google Play.
  • 30 днів технічної підтримки після релізу.
  • Документація по API та навчання персоналу (опціонально).

Терміни та вартість

Етап Термін
MVP (план поверху + real-time моніторинг) 8–12 тижнів
Повноцінна система (кілька об'єктів, графіки, алери, права) 4–6 місяців
Інтеграція з нестандартними протоколами +2–4 тижні

Вартість розраховується індивідуально після аналізу ваших контролерів та вимог. Зв'яжіться з нами для оцінки — ми підготуємо комерційну пропозицію за 2 робочих дні.