Реалізація сповіщень про критичні показники IoT-датчиків у мобільному додатку
Температура в серверній кімнаті піднялася до 45°C о 3 ночі. Push-сповіщення прийшло о 9 ранку — коли смартфон підключився до Wi-Fi. За цей час обладнання перегрілось. IoT-алерти — це завдання, де «сповіщення з затримкою» гірше, ніж відсутність сповіщення.
Чому стандартний FCM не підходить для критичних IoT-алертів
FCM нормальний приоритет (normal) буферизує доставку, коли пристрій у Doze Mode. Для некритичних сповіщень нормально. Для IoT-алертів — ні.
Потрібен "priority": "high" у FCM payload + на iOS apns-priority: 10 з interruption-level: critical. Останнє — особливий випадок: UNNotificationInterruptionLevel.critical відтворює звук навіть у режимі «Не турбувати» та при включеному беззвучному режимі. Потрібен спеціальний дозвіл com.apple.developer.usernotifications.critical-alerts, який слід окремо запросити у Apple.
Запит дозволу на критичні сповіщення — окремий проміпт, відрізняється від стандартного:
UNUserNotificationCenter.current().requestAuthorization(
options: [.alert, .sound, .badge, .criticalAlert]
) { granted, error in ... }
Користувач повинен явно дозволити критичні сповіщення — неможливо увімкнути без згоди.
Архітектура IoT pipeline
Датчики → MQTT-брокер (Mosquitto або AWS IoT Core) → серверний обробник → FCM/APNs.
MQTT — де-факто стандарт для IoT: легкий протокол, працює при нестабільному з'єднанні, підтримує QoS 0/1/2. Датчики публікують дані в топік sensors/{device_id}/temperature, сервер підписується на всі топіки пристроїв користувача.
Серверний обробник при отриманні повідомлення перевіряє значення проти порогових правил:
const rules = await getRulesForDevice(deviceId);
for (const rule of rules) {
if (rule.condition(value)) {
await sendCriticalAlert(userId, {
sensor: deviceId,
metric: rule.metric,
value,
threshold: rule.threshold,
severity: rule.severity
});
}
}
Дедупліка обов'язкова. Якщо датчик надсилає дані кожні 10 секунд і температура тримається вище порога 30 хвилин — це не 180 сповіщень, а одне з оновленням статусу. Redis: SET alert:{device}:{metric}:active 1 EX 1800 — поки ключ існує, нові алерти за цією умовою не відправляємо.
Багаторівнева система алертів
| Рівень | Приклад | FCM priority | iOS level | Дія |
|---|---|---|---|---|
| Info | Батарея датчика 20% | normal | passive | У штормі |
| Warning | Температура >35°C | high | active | Пробуджує екран |
| Critical | Температура >45°C | high | critical | Звук у беззвучному |
| Emergency | Датчик CO >200 ppm | high | critical | Звук + вібрація |
На Android аналогічно через notification channels з різним importance: IMPORTANCE_DEFAULT, IMPORTANCE_HIGH, IMPORTANCE_MAX.
Мобільний додаток: екран моніторингу
Dashboard з live-даними датчиків — реалізуємо через WebSocket з'єднання (не polling, щоб бачити оновлення в реальному часі при відкритому додатку). На Flutter: пакет web_socket_channel, дані в Riverpod StreamProvider.
Історичні графіки — fl_chart або syncfusion_flutter_charts. Зберігання історії на сервері в InfluxDB або TimescaleDB (розширення PostgreSQL) — обидва оптимізовані для часових рядів.
Налаштування порогових правил в додатку: користувач вибирає датчик, метрику, оператор (>, <, ==), значення, рівень критичності. Правила зберігаються на сервері.
Процес розробки
- Вибір MQTT-брокера та схеми топіків
- Розробка серверного обробника з дедупліцированням
- Налаштування FCM + APNs critical alerts дозволу
- Розробка мобільного клієнта (dashboard, налаштування алертів)
- Тестування доставки у Doze Mode і режимі «Не турбувати»
- Навантажувальне тестування (багато датчиків одночасно)
Терміни: від 4 тижнів (інтеграція з існуючою IoT-інфраструктурою) до 10–12 тижнів (повний стек з MQTT-брокером, серверною частиною та мобільним клієнтом).







