7. Умный дом, MQTT
Помимо приложения, с устройством можно взаимодействовать через MQTT, в том числе интегрировать в систему умного дома:
- WQTT - MQTT брокер + панель управления + навык для Алисы
- Домовёнок Кузя - панель управления + навык для Алисы
- И некоторые другие
Посмотреть все топики устройства можно во вкладке Инфо приложения. Здесь используются обозначения:
-
net
- имя сети -
device_id
- id устройства. Генерируется библиотекой (или задаётся вручную) -
client_id
- id клиента. В приложении генерируется автоматически, а для запросов через MQTT его нужно указать вручную. Можно просто написать mqtt. Можно придумать что то более сложное для безопасности, если в программе идёт ручная обработка запросов Request и проверка соответствия ID клиента. -
name
- имя виджета
Отправить новое значение (в payload) для виджета можно на топик:
net
/device_id
/client_id
/set/name
Для запроса значения нужно отправить пустое сообщение на топик:
net
/device_id
/client_id
/read/name
Получив это сообщение, устройство ответит текущим значением на get-топик, значение виджета будет прочитано в билдере.
Для получения значений с виджета нужно подписаться на топик:
net
/hub/device_id
/get/name
Для получения состояний устройства (включено/выключено) нужно подписаться на топик:
net
/hub/device_id
/status
Устройство отправит online
при выходе на связь и offline
при потере.
В библиотеке есть метод sendGet()
, отправляет значение указанного имени на get-топик:
sendGet(AnyText name, AnyValue value);
sendGet(AnyText name, double value, uint8_t dec);
Если нужно отправить значение с виджета - можно использовать sendGet(AnyText name)
. Функция вызовет билдер, прочитает значение с виджета и отправит на get-топик. Можно передать несколько имён виджетов списком через ;
.
Также есть "невидимый" виджет, который нужен только для привязки переменной к имени виджета: он не отображается в ПУ, но может отправлять и получать значения по MQTT.
Можно автоматически отправлять новое состояние на get-топик при изменении из приложения или MQTT set - sendGetAuto(bool state)
. По умолчанию функция отключена.
Для отправки состояния вручную нужно вызвать sendStatus(bool state)
.
uint8_t bright;
float temp;
void build(gh::Builder& b) {
// реальный виджет
if (b.Slider_("bright", &bright).click()) {
Serial.print("bright set to: ");
Serial.println(b.build.value);
}
// dummy виджет температуры
b.Dummy_("temp", &temp);
// по нажатию на кнопку отправить температуру в mqtt
if (b.Button().click()) hub.sendGet("temp", 123.45, 2);
}
void setup() {
// ..........
hub.sendGetAuto(true); // для отправки в mqtt при действиях с приложения
}
void loop() {
hub.tick();
// раз в 5 секунд отправлять значение виджета temp
static gh::Timer tmr(5000);
if (tmr) {
// задать случайное значение
temp = random(100) / 10.0;
// отправить из билдера
hub.sendGet("temp");
}
}
Например в wqtt добавляю новое устройство Лампочка.
Добавляю Органы управления, Яркость:
- Топик управления:
MyDevices/cb5bf63a/mqtt/set/bright
- Топик состояния:
MyDevices/hub/cb5bf63a/get/bright
Добавляю Датчик, Температура:
- Топик:
MyDevices/hub/cb5bf63a/get/temp
Настройки LWT:
- LWT Topic:
MyDevices/hub/cb5bf63a/status
- LWT Online Message:
online
Теперь установленная яркость прилетает в bright
, ползунок яркости в приложении GyverHub и в wqtt двигаются синхронно. Каждые 5 секунд отправляется случайная температура из билдера dummy. По нажатию на кнопку отправляется фиксированная температура, в качестве примера.