понедельник, 28 мая 2018 г.

Lazy MQTT: FAQ

О чем это


В этой статье собираются заметки, советы и решения проблем для программы Lazy MQTT (Play market), о которой я упоминал ранее в статье про умный дом. Это MQTT-клиент с огромными возможностями по оформлению и обработке сообщений для просмотра состояния и управления устройствами по MQTT.

У программы две версии: бесплатная (с рекламой) и платная (без рекламы). Вторая отличается еще поддержкой виджетов, в остальном они одинаковые и настройки можно переносить из одной в другую. Если нравится программа - напишите отзыв в Play Market, если хотите дополнительно отблагодарить автора - купите платную версию :)

Начало


1) Где получить больше информации о программе?
- в программу встроено общее описание с примерами (Меню->Помощь)
- в окне редактирования скрипта есть подсказка по встроенным функциям и переменным
- в программе есть демо-настройки
- в форуме 4PDA можно задать вопрос

2) Как экспериментировать с настройками или настроить программу для работы на другом устройстве?
- поддерживается 10 независимых наборов настроек, между которыми можно переключаться (Меню->Установках->Слот настроек)
- настройки можно экспортировать в текстовый формат и импортировать обратно для бэкапирования и переноса между устройствами (см. Меню->Настройки)

3) Как восстановить демо-настройки?
- Меню->Настройки->Импорт демо. Не забудьте предварительно переключить слот настроек на свободный в Установках, чтобы не потерять свои текущие настройки

4) С чего начать?
- посмотрите встроенное описание (Меню->Помощь)
- посмотрите примеры в Демо-настройках
- сделайте новую страницу (Меню->Страницы...->+) или используйте существующие
- добавляйте плитки. Если включить Меню->Режим дизайна, то плитки можно перемещать и менять их размеры пальцем

5) Как узнать причину ошибки (ошибка соединения, не работает скрипт и др.)?
- см. Меню->Текст последней ошибки

Оформление интерфейса


1) Каковы возможности по оформлению?
- плитки могут быть любого размера и располагаться в любом месте
- у плитки настраиваются цвета, текст заголовка/подвала, основой текст, иконка
- плитка может иметь два состояния с независимым оформлением (включена-выключена)
- плитки могут быть (полу-)прозрачными
- плитки могут перекрываться

2) Не хватает встроенных иконок. Что делать?
- при долгом нажатии на кнопку выбора иконки можно выбрать любую картинку на устройстве

3) Как задать цвет иконки отличный от цвета текста?
- можно сделать 2 Украшения:
а) основное украшение с цветом для текста
б) родитель для первого украшения с иконкой и цветом для нее

4) Что означают цвета точек на плитках?
- эти точки - статус данных и MQTT-соединения. Их можно отключать (Статус данных у Плитки)
- нет точки: изменено условие показа точки (Статус данных у Плитки) или у Плитки не указаны Данные, соединенные с каким-либо сервером 
- черный: устанавливается соединение
- светло-зеленый: соединение установлено, данные после этого не приходили
- зеленый: после соединения данные уже приходили
- красный и темно-красный - ошибка соединения
- желтый: после нажатия на плитку и отправки данных на сервер не получено подтверждение отправки. Например из-за плохого интернет-соединения

5) Как сделать радио-кнопки (несколько переключателей, когда выбор одного выключает все остальные)?
- сделайте несколько плиток, одна рядом с другой
- сделайте Данные к ним, у которых скрипт на отправку управляет сразу всеми этими Данными (например, данные d1, d2, d3. При активации d2 скрипт сбрасывает значения d1 и d3. Визуально значения обычно привязаны к статусу on-off)

6) Как к одной плитке подключить несколько слайдеров вo всплывающем окошке и отправлять их данные сразу по кнопке "Отправить"?
- сделать отдельную страницу со слайдерами (несколько плиток, у каждой слайдер) и плиткой "Отправить"
- при клике на плитку на основной странице открывается страница со слайдерами (в скриптах есть команда page="имя страницы" - переход на страницу)
- при клике на "Отправить" отправляются данные и происходит переход на основную страницу
- похожий пример есть в Демо, на странице с деревенским домом, у двери кнопка домофона

7) Возможно ли сделать шкалу на слайдере?
- cейчас шкалу можно сделать, если добавить на плитку со слайдером картинку с прозрачным фоном, на которой нарисована шкала, и подогнать настройкой ее размер и размер плитки, чтобы ровно ложилась на слайдер

8) Можно ли сделать промежуточный статус украшения, кроме 2-х существующих (on-off)?
- поверх основной плитки сделайте еще одну плитку (т.е. у нее z-координата д.б. больше)
- у новой плитки поставьте Данные, у которых нет скрипта на отправку и нет соединения - в этом случае она не будет хватать нажатия на нее, а пропускать их ниже себя
- у новой плитки поставьте одно украшение прозрачное, чтобы ее не было видно, а второе -  промежуточное, как вы хотите
- в скрипте основной плитки управляйте статусом Данных новой плитки, чтобы переключать ее Украшение
- вуаля, у вас есть три состояния

Работа с данными


1) Как расположить данные из нескольких источников на одной плитке?
- eсть Данные с именами d1 и d2
- создаем для общих данных новый элемент Данных my_data (к серверу подсоединять не требуется)
- у d1 и d2 указываем скрипт на прием, в котором пишем
my_data="data1:"+d1+"\ndata2:"+d2
- создаем плитку и указываем у нее Данные my_data. Все. Это один из вариантов

2) Если из скрипта отправляется сразу несколько сообщений с QoS=0, то почему до сервера доходит только одно из них?
- клиент не успевает послать сообщения и, вероятно, отбрасывает их, так как QoS=0 означает, что не очень-то и важно. Решение - поставить у Данных, которые отправляют такие сообщения, QoS=1

3) В скрипте управляют статусом данных (status="on"...), однако, статус сам сбрасывается. Что не так?
- проверьте флаг Авто "on" в Данных. Если он включен, то статус ставится автоматически. Если вы ставите его вручную, то выключите "Авто"

Скрипты


1) Как округлить число?
- Math.round(x)
- описание встроенных JavaScript функций и вообще языка: см. Rhino

2) Как написать скрипт, чтобы при изменении полученных данных с 0 на 1, было сообщение?
- скрипт:
if(this.my_old_data===undefined) my_old_data=null // нужно, если my_old_data - переменная
if(val==1 && my_old_data==0) notify('Заголовок', 'Текст', 'A')
my_old_data=val
- здесь my_old_data - имя переменной JS (значения переменных сохраняются между вызовами скриптов). Если существуют Данные с именем my_old_data, то значение my_old_data будет сохраняться и при выходе из программы (потому что значения Данных сохраняются)

3) При проверке моей переменной, пока она еще не определена, получаю ошибку ReferenceError: "zz" is not defined

if(val!=zz) zz=val // ошибка ReferenceError: "zz" is not defined
Перед проверкой значения переменной надо проверить, определена ли она:
if(this.zz===undefined) zz=null // если не определена, то определяем zz с пустым значением
if(val!=zz) zz=val // ошибки нет

Соединения


1) На плитке постоянно меняется цвет точки - то красная, то зеленая. Данные то отправляются, то пишет "нет соединения". Что происходит?
- это симптомы неверной настройки, когда несколько MQTT-клиентов, подключающихся к одному серверу имеют одинаковые Client ID (Имя Клиента). Client ID должен быть уникальным в пределах сервера. Client ID настраивается:
a) в Установках->Имя Клиента (предпочтительный способ)
б) в Соединении->Имя Клиента (следует использовать только если по какой-то причине вам нужно создать несколько Соединений к одному серверу, чтобы указать у них разные имена. В противном случае уберите имя из Соединения и используйте первый способ)

Режим работы с MQTT сервером


Lazy MQTT автоматически соединяется с сервером, если соединение потеряно, и специально следить за этим не нужно. Она также замечательно работает в сеансовом режиме (когда ее периодически запускают для просмотра или управления) и при обновлении содержимого виджетов по-расписанию.
При работе в постоянном режиме есть нюансы.
Lazy MQTT не будет поддерживать соединение с сервером, если устройство, на котором она запущена, засыпает (экономия батареи в первую очередь). Сервер в этом случае автоматически разорвет соединение по истечении таймаута (keep alive) умноженного на 2-3. По-умолчанию это порядка минут. Это не имеет значения, потому что программа, когда ей нужно, соединится сама. Имеет значение другое: даже если соединение есть, но устройство спит, сообщения не будут доходить сразу (ведь клиент спит). И тут возникает множество вариантов: сообщения QoS=0 могут вообще не прийти, когда программа спит, QoS>0 придут при просыпании программы, если соединение не было разорвано или даже если было, но у соединения сброшен флаг "Чистая сессия". В чистой сессии гарантированно придут retained-сообщения.

Отсюда выводы:
- Lazy MQTT на засыпающем устройстве нельзя использовать как устройство экстренного оповещения
- все сообщения о состоянии (именно состоянии), которые различные датчики и устройства посылают на MQTT-сервер, по-хорошему должны быть retained (потому что это их суть: если это состояние, то оно сохраняется до изменения, а не до момента прихода сообщения). Однако, многие устройства в этом плане поступают как попало. Решением может быть программа на сервере, которая автоматически перепубликует такие сообщения с флагом retained

Тогда возникает вопрос, на что влияет "время работы сервиса" в Установках Lazy MQTT, если работа программы при спящем телефоне все равно не возможна?
Указанное время работы позволяет не выгружать программу и ее настройки из памяти, поэтому повторный запуск происходит моментально. Кроме этого, если устройство не спит или часто просыпается, то сообщения приходить будут. И последнее: для устройства, которое постоянно не спит (например, панель управления на стене, которая никогда не выключается), режим с постоянной работой позволяет получать все сообщения сразу.

Lazy MQTT (платная версия) на спящем устройстве можно настроить для периодической проверки сообщений. Для этого нужно:
- создать виджет, в данных плиток виджетов должны быть указаны те Данные, которые для вас важны
- настроить время обновления виджетов в Установках
- при желании, поставить флаг "Будить устройство" там же (если его не ставить, то обновления будут происходить, если телефон разбудила какая-то другая программа)

О "Чистой сессии"
Если у соединения сброшен флаг "Чистая сессия", то сообщения будут приходить, даже если устройство спало или соединения не было. Приходить они будут, когда соединение появится и программа проснется. Это позволяет не пропускать сообщения, с одной стороны. С другой, такие задержанные сообщения могут прийти в программу не в том порядке, в котором они изначально появились. А это значит, что состояние устройства, например, может быть отображено неверно. Тут надо экспериментировать с вашим сервером.


Другое


1) Приложение само закрывается через какое-то время или не обновляет виджет
- приложение само не закрывается. Его может закрыть другое приложение или система. Этим грешат всякие экономщики батареи - нужно им сказать, чтобы они не трогали Lazy MQTT. Как их выключить - зависит от системы. Например, опция может называться Умное питание. На MUIU может быть так: заходим в настройки телефона, затем вкладка все приложения, находим Lazy MQTT, заходим в настройки приложения и ставим флаг "Разрешить Автозапуск". Не ясно как флаг с таким названием влияет на закрытие приложения, но помогает. Здесь статья на эту тему. Здесь список экономщиков от разных производителей телефонов и как их найти.