# Взаимодействие через MQTT Помимо приложения, с устройством можно взаимодействовать через MQTT, в том числе интегрировать в систему умного дома: - [WQTT](https://www.wqtt.ru/) - MQTT брокер + панель управления + навык для Алисы - [Домовёнок Кузя](https://alexstar.ru/) - панель управления + навык для Алисы - И некоторые другие ## Топики и обозначения Посмотреть все топики устройства можно во вкладке **Инфо** приложения. Здесь используются обозначения: - `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-топик, значение виджета будет прочитано в билдере. ## Топики для подписки ### Получение значений (get-топик) Для получения значений с виджета нужно подписаться на топик: `net`/hub/`device_id`/get/`name` ### Получение состояния Для получения состояний устройства (включено/выключено) нужно подписаться на топик: `net`/hub/`device_id`/status Устройство отправит `online` при выходе на связь и `offline` при потере. ## Отправка с устройства ### Напрямую В библиотеке есть метод `sendGet()`, отправляет значение указанного имени на get-топик: ```cpp sendGet(AnyText name, AnyValue value); sendGet(AnyText name, double value, uint8_t dec); ``` ### Из билдера Если нужно отправить значение с виджета - можно использовать `sendGet(AnyText name)`. Функция вызовет билдер, прочитает значение с виджета и отправит на get-топик. Можно передать несколько имён виджетов списком через `;`. Также есть "невидимый" виджет, который нужен только для привязки переменной к имени виджета: он не отображается в ПУ, но может отправлять и получать значения по MQTT. ### Авто get Можно автоматически отправлять новое состояние на get-топик при изменении из приложения или MQTT set - `sendGetAuto(bool state)`. По умолчанию функция отключена. ### Состояние Для отправки состояния вручную нужно вызвать `sendStatus(bool state)`. ## Пример ```cpp 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. По нажатию на кнопку отправляется фиксированная температура, в качестве примера.