Реализация взаимодействия с IoT-устройствами через мобильное приложение
IoT-интеграция — это не один протокол, а выбор между несколькими в зависимости от физической дистанции, требований к задержке и потреблению энергии. Приложение для управления умной лампой в соседней комнате и приложение для мониторинга промышленных датчиков на производстве используют разные стеки, но сталкиваются с одинаковыми проблемами: обрывы соединения, синхронизация состояния и обновление прошивки.
Выбор транспорта
| Протокол | Дальность | Энергопотребление | Типичное применение |
|---|---|---|---|
| BLE 5.0 | до 100м | очень низкое | носимые, датчики, замки |
| Wi-Fi | до 50м в помещении | среднее | умные розетки, камеры |
| Zigbee / Z-Wave | до 30м (меш) | низкое | умный дом |
| MQTT over TCP | через сеть | зависит от сети | промышленные датчики |
| Matter | до 50м | низкое | умный дом (новый стандарт) |
| Thread | меш | низкое | Matter-устройства |
Мобильное приложение чаще всего выступает в роли MQTT-клиента или BLE Central. Прямое управление Zigbee с телефона без хаба — редкость.
MQTT: самый распространённый IoT-транспорт
MQTT — pub/sub протокол поверх TCP. Брокер (Mosquitto, AWS IoT, HiveMQ) принимает сообщения и раздаёт подписчикам. Мобильное приложение подписывается на топики устройств и публикует команды.
iOS — MQTT-Client-Framework или CocoaMQTT:
import CocoaMQTT
let client = CocoaMQTT(clientID: "mobile-\(UUID().uuidString)", host: "broker.example.com", port: 8883)
client.username = "user"
client.password = "pass"
client.enableSSL = true
client.keepAlive = 60
client.delegate = self
client.connect()
// Подписка после connect:
func mqtt(_ mqtt: CocoaMQTT, didConnectAck ack: CocoaMQTTConnAck) {
guard ack == .accept else { return }
mqtt.subscribe("devices/sensor-01/temperature", qos: .qos1)
}
// Получение данных:
func mqtt(_ mqtt: CocoaMQTT, didReceiveMessage message: CocoaMQTTMessage, id: UInt16) {
if let payload = message.string {
let temp = Double(payload)
updateUI(temperature: temp)
}
}
// Публикация команды:
client.publish("devices/lamp-01/command", withString: "{\"state\":\"on\",\"brightness\":80}")
Android — Paho MQTT Android Service или HiveMQ MQTT Client:
// HiveMQ (более современный, без deprecated API)
val client = MqttClient.builder()
.useMqttVersion5()
.serverHost("broker.example.com")
.serverPort(8883)
.sslWithDefaultConfig()
.simpleAuth()
.username("user")
.password("pass".toByteArray())
.applySimpleAuth()
.buildAsync()
client.connect().whenComplete { _, throwable ->
if (throwable == null) {
client.subscribeWith()
.topicFilter("devices/sensor-01/temperature")
.qos(MqttQos.AT_LEAST_ONCE)
.callback { publish ->
val payload = String(publish.payloadAsBytes)
// обновляем UI через Handler или LiveData
}
.send()
}
}
QoS и его влияние на надёжность
-
QoS 0— at most once. Быстро, без подтверждения. Для частых обновлений (температура каждую секунду) — нормально. -
QoS 1— at least once. С подтверждением, возможны дубли. Для команд (включить/выключить) — минимум. -
QoS 2— exactly once. Гарантия доставки без дублей. Для платёжных операций, критических команд.
Last Will Message
MQTT позволяет задать сообщение, которое брокер отправит при неожиданном отключении клиента. Для IoT это важно: если телефон ушёл в оффлайн, другие клиенты должны это знать:
client.willMessage = CocoaMQTTMessage(
topic: "clients/mobile-app/status",
string: "{\"online\":false}"
)
Синхронизация состояния устройств
Главная архитектурная проблема: приложение открылось — какое сейчас состояние всех устройств? MQTT не хранит историю по умолчанию. Решения:
Retained messages. Устройство публикует своё состояние с флагом retain = true. Брокер хранит последнее сообщение и сразу отдаёт при подписке. Мобильное приложение при старте подписывается на devices/+/state и получает актуальные состояния.
Shadow/Digital Twin. AWS IoT Device Shadow, Azure Device Twin — REST API для чтения последнего известного состояния устройства. Подходит когда состояний много и retained MQTT недостаточно.
OTA-обновления прошивки
Если устройство поддерживает обновление через мобильное приложение (BLE OTA или MQTT), это отдельная задача. Стандарты: Nordic DFU (для nRF-чипов через BLE), ESP-IDF OTA через HTTP/MQTT, MCU Bootloader через UART-bridge.
Nordic DFU на iOS — iOSDFULibrary, на Android — Android-DFU-Library. Обе официальные библиотеки от Nordic Semiconductor.
Фоновая работа и уведомления
Мобильное приложение не может держать MQTT-соединение в фоне постоянно. Для уведомлений о событиях устройств — APNS/FCM: брокер или backend отправляет push при изменении состояния.
На Android WorkManager + ForegroundService позволяют держать MQTT-соединение при необходимости. На iOS — Background App Refresh с ограничением времени выполнения.
Срок интеграции: от 1 недели (MQTT-клиент с базовым управлением) до 3-4 недель (полный стек с OTA, синхронизацией состояния, push-уведомлениями). Стоимость рассчитывается индивидуально.







