Добрый день, уважаемый читатель! В этой статье я расскажу, как настроить один из клиентов MQTT для Android – MQTT Dash и сделать из старого смартфона или планшета удобную панель управления умным домом.
Необходимое предупреждение: предполагается, что вы знаете, что такое протокол MQTT, с чем его едят, и для чего “оно” нужно. В данной статье я не буду касаться этих вопросов.
В данной статье все настройки я буду делать применительно к статье “Термостат на ESP32 с удаленным управлением. MQTT-топики“, но вы можете использовать её как руководство для своих устройств, в том числе и на Arduino.
Если вы установите и запустите MQTT Dash в первый раз, то оно вряд ли впечатлит вас – уж слишком простой и незатейливый интерфейс оно имеет. Но, несмотря на внешнюю простоту, это приложение имеет мощный потенциал (хотя и без недостатков). Я много раз пытался перейти на другие приложения, но пока мне это не удалось.
Требования к приложению
Для начала изложу свои требования к MQTT панели управления, исходя из них я и остановил свой выбор на MQTT Dash на текущий момент. На самом деле требований не так уж и много…
- Блокировка гашения экрана смартфона. Я использую для управления умным домом не только свой основной смартфон, но и старые, бывшие в употреблении, устройства – смартфоны или планшеты в качестве стационарных панелей управления. Поэтому мне необходим такой режим, когда экран устройства остается активным неограниченное время. Несмотря на обилие MQTT клиентов в Google Play, очень не много поддерживают данную функцию.
Предупреждение! Постоянно включенный экран устройства может привести к его быстрой (экрана) деградации (“выгоранию”). Чтобы избежать этого, можно предусмотреть включение экрана посредством датчика движения или просто выключать экран устройства хотя бы на ночь.
- Компактность отображения. Поскольку у меня уже достаточно много устройств, и исходя из применения программы для панели управления, мне крайне желательно вместить на одном экране как можно больше информации и (или) органов управления. Для рабочего смартфона прокрутить экран – не проблема, а вот для панели управления – это не удобно. Из требований компактности я отказался от использования различных “красивошных” шкал и секторов, которые сразу же “отъедают” приличный кусок экрана в пользу многострочных данных.
- Поддержка раздельных sub и pub топиков. Далеко не все клиенты MQTT для Android позволяют организовать управление устройством “с подтверждением”, то есть через два раздельных топика.
- Поддержка JSON-формата. На самом деле большинство клиентов клиенты MQTT для Android умеют извлекать данные из JSON, но почему-то некоторые достаточно продвинутые программы не имеют такой простой функции.
- Поддержка скриптов. Встроенные Java-скрипты позволяют делать “финт ушами” в случае необходимости, например перенести второстепенные обработки данных с устройства на планшет или смартфон.
Кроме героя сегодняшней статьи, я перепробовал множество клиентов, и практически в каждом из них обнаруживался тот или иной “косяк”. MQTT Dash тоже не без недостатков, их я опишу чуть позже, но в целом и общем оно меня вполне устраивает.
Приложение способно нормально работать на древних версиях Android (если не ошибаюсь – начиная с Android 4), поэтому его смело можно устанавливать на очень старые телефоны и планшеты.
Очень удручает тот факт, что создатель данного приложения перестал заниматься доработками данного приложения, а с некоторых пор вообще перестал выходить на связь на форуме и отвечать на вопросы. Увы и ах, приходится работать с тем, что есть.
Установка приложения
Думаю, с установкой проблем возникнуть не должно. Переходим по ссылке ниже (или со смартфона открываем Google Play и вбиваем в поиске MQTT Dash), затем жмем “Установить”. Ждем установки и запускаем…
Настройка подключения
Если вы ещё ни разу не пользовались данным приложением, то при первом запуске вы получите неприглядный темный экран. Для начала работы вам необходимо создать хотя бы одно подключение к брокеру. Вы можете создать несколько отдельных подключений даже к одному и тому же серверу, например чтобы сгруппировать элементы управления по какому-то признаку.
Для создания нового подключения нажмите ➕ в правом верхнем углу приложения:
Затем нужно указать параметры вашего сервера. Я надеюсь, вы знаете что такое MQTT брокер и с чем его едят. Итак, указываем адрес сервера, порт подключения (я рекомендую использовать TLS-соединение, если это возможно), имя пользователя и пароль:
Размер плиток на современных экранах лучше поставить “маленький”. В конце не забудьте нажать “Записать” опять же в правом верхнем углу экрана. Затем попробуйте нажать на только что созданное подключение – вы должны “провалиться” на ещё один черный экран и при этом не должно быть никаких ошибок. Если всё хорошо, можно добавлять топики для отображения.
Добавление плиток с данными
Как я уже упоминал, все примеры в данной статье будут рассматриваться в применении к “Термостату”, который я описывал в предыдущих статьях.
Я буду приводить примеры для настроек топиков CONFIG_MQTT1_PUB_LOCATION = “other” и CONFIG_MQTT1_PUB_DEVICE = “thermostat”, при повторении учитывайте свои настройки!
Исходя из того, что большинство данных с термостата “приходит” в JSON виде, настройки будут выполняться для извлечения данных из JSON-пакета. Если вы не используете JSON, то это ещё проще.
Совет: если вы плохо ориентируетесь, какие топики и в каком виде публикует ваше устройство, то рекомендую вначале установить на компьютер бесплатное приложение MQTT Explorer, с помощью которого легко просматривать все данные с вашего устройства или устройств:
Добавляем “часики”
На смартфоне дополнительный вывод информации о дате и времени не требуется; но на панели управления, которая постоянно включена – это очень полезная функция, так как системная панель скрыта (MQTT Dash работает в полноэкранном режиме). Опять жмем ➕ в правом верхнем углу и выбираем тип “Текст”:
Затем вводим следующие данные:
После сохранения вы должны получить такую картинку:
Ну это было слишком просто и не интересно…
Добавляем данные с сенсора с экстремумами
Ну это было слишком просто и не интересно. Давайте чуть-чуть посложнее – добавим отображение “совмещенных” данных с датчика температуры и влажности, допустим это будет aht10. Прошивка публикует достаточно сложный JSON, в котором содержится вся информация о данных, полученных с сенсора, времени измерения и зафиксированных минимумах и максимумах за разные периоды времени.
Еще раз добавляем плитку типа “Текст” и указываем уже такие параметры:
Сохраняем:
Отлично, все получилось.
Поле “display“, которое мы использовали, содержит последние измеренные данные для температуры и влажности одновременно. Оно удобно ещё и тем, что в случае какого-либо сбоя вместо данных в нем будет отображаться состояние датчика:
Но при необходимости, вы можете отображать температуру и влажность отдельно. Для этого просто необходимо использовать другие поля JSON-пакета.
Теперь давайте добавим плитки, которые будут отображать минимумы и максимумы температуры за текущие сутки. Для этого нужно создать ещё одну плитку, но JSON поле “display” в ней заменить на “temperature.extremums.daily.min.tsv“:
Что это означает:
- temperature – мы хотим видеть данные температуры
- extremums – мы хотим видеть экстремумы
- daily – за текущие сутки
- min – минимальное значение
- tsv – данные, совмещенные с днем и временем измерения, когда был зафиксирован этот минимум
Клонирование плиток
Теперь нужно добавить очень похожую плитку – , но уже для максимального значения. Чтобы не вводить одни и те же данные повторно, можно поступить гораздо быстрее:
- нажмите и удерживайте плитку до появления меню
- выберите пункт “Клонировать” – у вас появится копия плитки
- отредактируйте параметры копии как вам требуется.
В нашем случае нужно всего лишь заменить “temperature.extremums.daily.min.tsv” на “temperature.extremums.daily.max.tsv“:
Ну это тоже не сильно сложно, просто нужно ориентироваться, где “лежат” нужные вам данные в опубликованном JSON пакете. Более подробно изучить структуру JSON удобнее с компьютера и приложения MQTT Explorer.
Отображение состояния нагрузки
Отображать состояние нагрузки (котла, лампы, вентилятора и т.д.) проще всего в виде плитки типа “Переключатель/кнопка”. Ну тут совсем просто, я даже не уверен, что вам понадобится какая-либо помощь. Добавляем новую кнопку, выбираем тип “Переключатель/кнопка”, указываем топик, выбираем пиктограммы для включенного и выключенного режима, их цвета. Все!
А что делать, когда необходимо отобразить несколько состояний нагрузки в виде пиктограммы? Например у кухонной вытяжки есть три скорости. Или охранная сигнализация может находиться в нескольких состояниях: отключено, частичная охрана, полная охрана. Конечно, можно обойтись текстом, но это не наш метод. На помощь придет плитка “Мульти-выбор”: добавьте нужное количество опций, а в качестве текста используйте стандартные emoji:
или так:
Во втором случае я кроме собственно emoji добавил ещё и текст.
Настройка параметров с подтверждением
Использование приложения для управления устройством почти ничем не отличается от отображения данных – просто поставьте галочку “Включить публикацию“. После этого можно нажимать на плитку и вводить какие-либо данные, они будут отправлены в указанный в плитке топик. Но это справедливо, если вы используете топик настроек только “на вход”, без подтверждения получения изменений со стороны устройства.
Я использую управление устройством с подтверждением. В этом случае отправка какого – либо параметра на устройство производится в несколько этапов:
- В момент запуска и подключения к MQTT устройство публикует все известные ему параметры (которые хранятся в памяти NVS) в разделе
confirm<LOCATION>/<DEVICE>/
/чего-то/там
. MQTT Dash отображает актуальные данные в плитках, относящихся к параметрам и настройкам. - При изменении любого параметра мы должны отправить новое значение в немного другой топик:
config<LOCATION>/<DEVICE>/
/чего-то/там
. - Получив эти данные, устройство проверяет значение, применяет куда надо и записывает его в хранилище NVS, и только после этого отправляет его обратно в
confirm<LOCATION>/<DEVICE>/
/чего-то/там
. - После чего MQTT Dash отображает новое значение в плитке. Цикл завершен.
Если на любом этапе что-то пошло не так – клиент MQTT на смартфоне должен “откатить” отправленное значение.
MQTT Dash прекрасно подходит для такой схемы работы. Делается это очень просто:
Здесь следует обратить внимание на следующие моменты:
- Не забудьте поставить флажок “Включить публикацию“. Под публикацией здесь понимается запись данных на устройства.
- Топики sub (чтение данных с устройства) и pub (запись данных на устройства) должны быть различными
- Если вы хотите быть уверенными, что устройство подтвердило получение – установите флажок “Включить промежуточный статус” и задайте “Таймаут промежуточного статуса“
Главное – чтобы ваше устройство поддерживало такую схему работы
Используем Java-обработчики
Предыдущие разделы выглядят очень просто. Давайте разберемся, как можно применять скрипты и для чего это нужно. Для начала немного теории.
MQTT Dash поддерживает три обработчика (скрипта) для каждой плитки:
- ON RECIEVE– данный скрипт будет вызван при получении нового пакета данных с устройства
- ON DISPLAY– данный скрипт будет вызван при перерисовке плитки
- ON TAP– данный скрипт будет вызван при нажатии на плитку, если она публикуемая
Обработчики ON RECIEVE
и ON DISPLAY
, в принципе, очень похожи. Я чаще пользуюсь ON DISPLAY
, так как ON RECIEVE
почему-то сильнее “подтормаживает”.
Рассмотрим простой пример.
Изменение цвета текста на плитке
Допустим, у нас есть топик “other/thermostat/status
“. В нем публикуется информация о состоянии устройства:
- OFFLINE – устройство выключено (через LWT)
- ONLINE – устройство включено
- Затем устройство периодически публикует сюда сюда краткую системную информацию в виде трех строк. Первая строка – время наработки устройства с момента последнего запуска в формате ДНИ : ЧАСЫ : МИНУТЫ. Вторая строка – уровень сигнала WiFi. Третья строка: первая цифра – количество свободной кучи в %; затем идет количество зафиксированных ошибок выделения памяти; и в конце оставшийся объем свободных записей в разделе хранения параметров NVS.
Информация в этом топике публикуется в открытом виде, без JSON.
Настроим плитку:
Поскольку здесь не используется JSON, строку JSON path оставляем пустой.
Работает, но скучно и не интересно. Давайте раскрасим плитку и заставим её мигать, если устройство не доступно. Для этого найдите кнопку ON DISPLAY и нажмите её – вы попадете в редактор скриптов:
Добавьте сюда следующий текст:
if (event.getLastPayload() == 'OFFLINE') { event.textColor = '#ff0000'; event.blink = true; event.text = 'Устройство выключено или offline'; } else { event.textColor = '#9acd32'; event.blink = false; };
Что делает этот скрипт? Если было получено сообщение “OFFLINE”, то текст сообщения заменяется на более удобочитаемое “Устройство выключено или offline“, включается режим мигания и устанавливается красный цвет текста. Иначе отключаем режим мигания и устанавливаем спокойный зеленоватый цвет текста. Как видите – очень не сложно.
Примечание: включить мигание можно и без использование скриптов, так сказать, “штатными средствами”. А вот поменять цвет текста без скрипта не получится.
Расчёт потребляемой мощности
Другой пример применения скриптов – пересчет полученных значений. Предлагаемая мной прошивка кроме статуса нагрузки “умеет” учитывать отработанное время в секундах: за последнее включение, за сутки, неделю, месяц и т.д. Зная время работы и мощность нагрузки, можно легко посчитать количество потраченных киловатт-часов по простой формуле:
кВт*ч = <мощность в кВт> * <кол-во секунд> / 3600
В этом случае скрипт будет уже чуть посложнее:
Это вариант скрипта для расчета данных за сутки. Для других временных периодов нужно будет подобрать другие множители.
function twoDig(value) { if (value>9) { return value; } else { return "0"+value; }; }; var total=event.text; var secs=total; var hour=Math.trunc(secs/3600); secs=secs-hour*3600; var mins=Math.trunc(secs/60); secs=secs-mins*60; event.text=twoDig(hour)+":" +twoDig(mins)+":" +twoDig(secs)+"\n" +Math.round(10000.0*total/(3600*24))/100+"%\n" +Math.round(total*19/3600)/1000+" кВт/ч";
Выглядит в результате это вот так:
Вы также можете скачать скрипты с GitHub: https://github.com/kotyara12/telemeter_dzen/tree/master/java
- В первой строке отображается время работы в формате: ДНЕЙ.ЧАСЫ:МИНУТЫ:СЕКУНДЫ
- Вторая строка в процентах – время работы от общего времени суток, недели и т.д.
- Третья строка – потреблённая мощность в кВт*ч. Для вентилятора может это и не актуально (но пусть будет), а вот для какого-нибудь тепловентилятора цифры будут гораздо менее скромными.
У меня используется ещё несколько скриптов, но об них поговорим в следующий раз, когда будет соответствующая тема.
Придумайте свои варианты использования скриптов…
Перенос настроек с одного телефона на другой
Итак, вы настроили панель управления. Как теперь перенести её на другой телефон? Неужели придется всё проделать заново – все эти топики, скрипты, настройки? Нет, автор всё предусмотрел. Создайте и откройте необходимое соединение на новом телефоне и нажмите кнопку со стрелками в верхнем правом углу. У вас откроется вот такое окошко:
Нажмите кнопку “Подписаться и ждать метрики“. Затем на телефоне-источнике повторите те же самые действия, но в конце нажмите “Опубликовать метрики“. Несколько мгновений – и все настройки будут перенесены.
Эта же операция позволяет сохранять разные варианты настроек для разных устройств на MQTT брокере постоянно. Для этого необходимо вручную изменить топик на уникальный, например “metrics/exchange/thermostat/2022-10-21
” и опубликовать их с RETAINED. Теперь вы всегда сможете загрузить данную копию настроек (пока ваш брокер хранит их).
Согласитесь, это очень удобно.
Чего не хватает в данной программе
Идеальных приложений нет, MQTT Dash – не исключение. Мне очень нравится MQTT Dash, но я периодически пытаюсь найти для себя ещё более лучшее приложение. Пока – безрезультатно, но всё может измениться в любой момент. Итак – чего же мне не хватает?
- Очень не хватает возможности изменять цвет фона плитки, хотя бы с помощью скриптов. Оптимально было бы визуально группировать плитки одинаковым фоном, тогда как цвет текста можно было бы использовать для отображения состояния.
- Нет возможности программно изменять размер текста. Идея состоит в том, что при многострочном тексте основной текст выделять более крупным шрифтом, второстепенный – более мелким.
- Нет возможности разместить в плитке более трех строк текста. Иногда это нужно. Вообще, MQTT Dash мало приспособлен для вывода “длинной” текстовой информации.
- Клонирование плиток есть, а клонирования соединений нет. Между тем, часто приходится использовать одни и те же параметры подключения, так как устройств много, а сервер один и тот же.
- Не хватает возможности быстро переключаться между соединениями – например можно было бы листать их “влево-вправо”.
Но увы, автор достаточно давно перестал выпускать новые версии программы. Приходится пользоваться тем, что есть.
Вместо заключения
Данная не охватывает все варианты использования MQTT Dash, некоторые опции я вообще не использую (например картинки). Если вам не ясны какие-то моменты – пожалуйста, оставляйте свои комментарии.
На этом пока всё, благодарю за внимание. До встречи на сайте и на dzen-канале!
💠 Полный архив статей вы найдете здесь
Пожалуйста, оцените статью:
А всякие Blynk, RemoteXY, Virtuino (Virtuino MQTT, Virtuino IoT) не рассматривали?
Это не чисто MQTT даши, а даже больше. Могут работать с MQTT, с облаком (в том числе собственным) или напрямую через websocket (Virtuino IoT). Причем у них довольно развитые наборы кнопок, датчиков, панелей, графиков, анимации, видео наблюдения за процессом и т.д.
Правда обладают в той или иной степени платностью.
Рассматривал.
— Blynk даже сервер стоит до сих пор на домашнем сервачке. Не зашло
— Virtuino пробовал разные. Но что-то толи не разобрался, то ли еще что-то. Не зашло. У меня десятки устройств, сотни топиков, все почти в JSON – там замучаешся настраивать.
— RemoteXY даже не слышал про такое
Virtuino MQTT- наше все. Про JSON нет планов написать статью? Ну не врубаюсь я в JSON. Толи я дурак, толи лыжи не едут
Повторюсь – в Virtuino хоть и много возможностей, но очень сложно настраивать. Из-за этого например управление теплицей с десятками датчиков и исполнительных устройств превратится в каторгу.
Ну а про JSON можно написать, почему бы нет…
Изменить фон самой плитки мне не удалось, но вот фон текста (верхнего, основного и нижнего) получилось. Если их выставить в одно значение и подобрать ширину/высоту, то можно добиться раскрашивания всей плитки одним цветом.
ON DISPLAY:
var brcolor1 = -16711936;
var bgcolor1 = 0;
var brcolor2 = -16711936;
var bgcolor2 = 0;
var brcolor3 = -167936;
var bgcolor3 = 0;
var view = event.tile;
if(view.getChildAt(1).background == null){
var classLoader = view.getClass().getClassLoader();
var loadedClass = classLoader.loadClass(“android.graphics.drawable.GradientDrawable”);
var b1 = loadedClass.getDeclaredConstructor().newInstance();
b1.setStroke(4, brcolor1);
b1.setColor(bgcolor1);
var b2 = loadedClass.getDeclaredConstructor().newInstance();
b2.setStroke(4, brcolor2);
b2.setColor(bgcolor2);
var b3 = loadedClass.getDeclaredConstructor().newInstance();
b3.setStroke(4, brcolor3);
b3.setColor(bgcolor3);
view.getChildAt(0).setBackgroundDrawable(b1);//top text
view.getChildAt(1).setBackgroundDrawable(b2);//main text
view.getChildAt(2).setBackgroundDrawable(b3);//bottom text
}
//Высота основного текста. можно не использовать.
var mainLayout = view.getChildAt(1).getLayoutParams();//main text
mainLayout.height = 300;
view.getChildAt(1).setLayoutParams(mainLayout);