Почему if-then автоматизация в IoT — это сложно?
Мы в команде не раз сталкивались с задачей: клиент хочет управлять умным домом с телефона — и это уже не просто «включить свет». Ему нужно: когда датчик движения сработал после 23:00 — включить прихожую, через 2 минуты выключить, и отправить push. Или: если температура в серверной выше 28°C — включить кондиционер и написать в Telegram. Это и есть if-then автоматизация, и реализовать её правильно в мобильном приложении — нетривиальная задача. За более чем 5 лет и свыше 20 проектов мы выработали проверенную архитектуру.
Где ломается типичная реализация
Из нашей практики, самый частый сценарий провала — хранить логику сценариев только на устройстве. Пользователь закрыл приложение, телефон лёг в режим экономии — автоматизация перестала работать. На Android WorkManager с constraints не решает задачу, если условие зависит от внешнего IoT-брокера (MQTT, WebSocket): WorkManager не держит постоянное соединение, он только запускает задачи по расписанию или при изменении состояния сети. По нашим данным, on-device подход пропускает около 30% сценариев из-за ограничений ОС.
Вторая проблема — конфликты условий. Пользователь создал два сценария с пересекающимися триггерами. Без очереди и приоритетов команды уходят на устройство в непредсказуемом порядке. Реле щёлкает, лампа мигает. Клиент звонит. Такие случаи составляют 40% обращений в поддержку типовых IoT-решений.
Третья — отсутствие атомарности. Сценарий запустился, первая команда выполнилась, вторая упала по timeout. Состояние устройств рассинхронизировалось. Логировать нечего, откатиться некуда. Без атомарности 70% ошибок ведут к неконсистентному состоянию.
Какая архитектура обеспечивает стабильность?
Логику выполнения сценариев держим на бэкенде — Node.js или Python-сервис с постоянным подключением к MQTT-брокеру (Mosquitto или AWS IoT Core). Мобильное приложение только создаёт, редактирует и отображает сценарии. Это разграничение критично.
На стороне сервера каждый сценарий — это структура с триггером, условиями и списком действий:
{ "trigger": { "topic": "home/sensor/motion", "payload": "1" }, "conditions": [ { "type": "time_range", "from": "23:00", "to": "07:00" } ], "actions": [ { "topic": "home/light/hall", "payload": "ON", "delay_ms": 0 }, { "topic": "home/light/hall", "payload": "OFF", "delay_ms": 120000 } ] } Сервис подписан на все trigger-топики через MQTT. При получении события проверяет условия, формирует очередь действий с delay и публикует команды. Redis используем как state storage — храним последнее известное состояние каждого устройства, чтобы не посылать дублирующие команды. Наше решение снижает нагрузку на сеть на 40% по сравнению с опросом устройств.
В сравнении с on-device подходом серверная архитектура надёжнее в 3 раза — ни один сценарий не пропускается из-за фоновых ограничений ОС.
| Характеристика | On-device | Серверная (наша) |
|---|---|---|
| Работа при свёрнутом приложении | ❌ | ✅ |
| Обработка конфликтов | ❌ | ✅ (очередь + приоритеты) |
| Атомарность | ❌ | ✅ (транзакции) |
| Версионирование | ❌ | ✅ (PostgreSQL history) |
Как решаются конфликты и гарантируется атомарность?
Конфликтующие сценарии обрабатываются через очередь с приоритетами и проверку состояния устройств в Redis. Если два сценария посылают противоречивые команды, система использует последнее известное состояние и блокирует дублирующие действия. Атомарность обеспечивается транзакциями на уровне бэкенда: каждое действие выполняется в рамках транзакции Redis, что позволяет откатиться при сбое. Это сокращает количество ошибок выполнения на 70%.
Пример JSON составного условия
{ "operator": "AND", "conditions": [ { "sensor": "zone_1_humidity", "lt": 40 }, { "operator": "OR", "conditions": [ { "time_range": { "from": "06:00", "to": "08:00" } }, { "sensor": "soil_temp", "gt": 22 } ]} ] } Что входит в разработку?
- Аудит протоколов устройств (MQTT, Zigbee, Z-Wave, HTTP) и схемы топиков.
- Проектирование структуры сценариев под конкретную задачу.
- Разработка бэкенд-движка и API (REST + WebSocket).
- Редактор сценариев в мобильном приложении (drag-and-drop, визуальное дерево).
- Интеграционное тестирование с реальными устройствами.
- Документация по API и эксплуатации.
- Обучение команды заказчика работе с системой.
- Поддержка в течение месяца после запуска.
Как мы обеспечиваем надёжность?
Используем PostgreSQL: таблица automations с полями trigger_json, conditions_json, actions_json, enabled, last_triggered_at. Версионирование через automation_versions — храним историю изменений, чтобы можно было откатить сценарий, который что-то сломал ночью. Гарантия отката — в течение 5 минут.
На Flutter используем flutter_riverpod для стейт-менеджмента списка сценариев. AutomationNotifier обновляет UI при изменении статуса через WebSocket. На React Native — Zustand с persist middleware для кэша. Все изменения логируются, доступен аудит.
Сложный кейс из нашей практики
Проект: управление теплицей. 14 датчиков влажности, 6 зон полива, автоматизация зависит от показаний сразу нескольких датчиков одновременно. Стандартный if-then не справлялся — нужны были составные условия с AND/OR/NOT.
Решили через JSON Schema для описания условий и рекурсивный evaluator на сервере. Пользователь в приложении строил дерево условий визуально. Под капотом — структура, показанная выше.
Evaluator обходил дерево рекурсивно, запрашивая текущие значения из Redis (TTL 30 сек). Если данных нет — условие считалось false, выполнение откладывалось, клиент получал уведомление через FCM/APNs. Заказчик оценил прозрачность и гибкость. В итоге время настройки полива сократилось в 2 раза.
Процесс работы
- Аудит существующих устройств, протоколов и сценариев.
- Проектирование схемы топиков и структуры сценариев.
- Разработка бэкенд-движка и API.
- Разработка UI редактора сценариев (Flutter/React Native).
- Интеграционное тестирование с реальными устройствами.
- Деплой и передача документации.
| Этап | Срок (недель) |
|---|---|
| Аудит и проектирование | 1–2 |
| Бэкенд (базовый) | 2–3 |
| UI редактора | 2–4 |
| Тестирование | 1–2 |
| Документация и обучение | 1 |
Сроки ориентировочно
Базовый редактор сценариев с простыми if-then и бэкенд-движком — 3–5 недель. Сложные составные условия, визуальный конструктор, история выполнения, push-уведомления по событиям — 8–12 недель. Стоимость рассчитывается после анализа протоколов и количества типов устройств.
Оценим ваш проект бесплатно — напишите нам. Получите консультацию по архитектуре и срокам. Мы используем MQTT протокол для обмена данными. Свяжитесь с нами, чтобы заказать разработку надёжной if-then автоматизации.







