Настройка процесса отправки сообщений по MQTT-мосту

Добрый день!

Возник следующий вопрос. Можно ли каким-либо способом регламентировать процесс отправки сообщений удаленному MQTT-брокеру? В частности производить их отправку только в том случае, когда значение изменилось (отлично от предыдущего) или через заданный промежуток времени. Чтобы сообщения не сыпались валом. Я прочитал несколько веток на форуме, но к сожалению не сложил для себя пока ясной картины. Видимо сказывается отсутствие некоторого опыта и знаний. Буду рад, если разъясните и подскажите направление поиска/действия.

Добрый день!
Для прямого ответа на ваш вопрос нужно смотреть документацию по настройке MQTT-моста в брокере. Можете погуглить по запросу “mosquitto bridge settings”. Я ничего подобного не делал, всегда настраивал мост только с трансляцией всех сообщений.
Если сообщения у вас появляются про опросе устройств RS-485 нашим стандартным драйвером, то можете настроить частоту опроса устройств в нём.

ещё обратите внимание, что большинство наших драйверов и так отправляют сообщения в MQTT только если значения поменялись

Если нужно передавать не все значения, то можно просто создать отдельный топик для бриджа, и туда перезаписывать нужные значения по таймеру или по нужному событию. Мы делаем так.

1 лайк

Коллеги, благодарю за ответы.

Уважаемый Demix, я думал про такой вариант, но пока нет достаточного багажа знаний, чтобы реализовать. Я так понимаю это можно сделать с помощью правила. Не сочтите за наглость, можно ли попросить небольшой пример? Если не затруднит.

Создаем виртуальные устройства, для всех параметров, которые нам нужно передавать через бридж.

Пример для двух показаний, можно размножить до нужного Вам количества:

defineVirtualDevice("Sensors", {
	title : "Датчики",
	cells : {
		T1 : {
			type : "text",
			value : 0
		},
		T2 : {
			type : "text",
			value : 0
		}
	}
});

В настройках бриджа подписываемся на этот топик Sensors со всеми подтопиками:

topic /# out 1 /devices/Sensors/controls /topik_on_server

И теперь просто пишем необходимое правило, по которому нужно собирать и отправлять показания.
Для этого, в теле функции, в созданные нами виртуальные устройства записываем необходимые показания:

dev[“Sensors”][“T1”] = тут путь к нужному показателю.

Например правило, которое отправляет раз в час состояние выходов А1 и А2:

defineRule(“sendDataToServer”, {
when: cron("@every 1h00m"),
then: function () {
dev[“Sensors”][“T1”] = dev[“wb-gpio”][“A1_OUT”] ;
dev[“Sensors”][“T2”] = dev[“wb-gpio”][“A2_OUT”] ;
}
});

Правило можно написать и по таймеру, и по сработке определённых датчиков. Если что-то не понятно, то спрашивайте.

1 лайк

Demix,

Благодарю Вас за ответ. Как рас разбираюсь во всех тонкостях. Если будут вопросы обязательно напишу.

Евгений,

Согласен. Но что делать со значениями, которые колеблятся во втором/третьем знаке после запятой и эти колебания просто неважны и отправлять их брокеру нет необходимости? Или ситуация, когда значение колеблется в малой окрестности допустимого значения и этим колебанием хочется пренебречь. Исключить, так сказать, “шумы”. Смысл спамить облако?

Создавать кучу виртуальных устройств, которые будут функционировать с этой точки корректно тоже не выглядит хорошим решением. Есть ли все-таки способ централизовать процесс? Капнуть глубже виртуальных устройств и скриптов-правил.

Благодарю еще раз. Ваша подсказка помогла. Разобрался со скриптами-правилами, научился делать свои интерактивные элементы управления и в реальном времени управлять процессом отправки данных брокеру (по таймеру в заданное время, через заданный промежуток времени, по выходу из диапазона допустимых значений и т.п.). Но… теперь куча виртуальных устройств и объемные скрипты. Так и не найду никак ответ на вопрос… Можно ли изначально прописать правила обработки показаний, так сказать, на низком уровне…?

Интересует не конкретно RS-485, а отправка сообщений в целом. Моя задача исключить “шумы” при отправке сообщений. В случае если величина изменилась незначительно с прошлого раза ее не нужно отправлять вовсе. Смысл? Засорять канал и отправлять брокеру излишние данные. Куда эффективнее контролировать и регламентировать процесс. Особенно, если речь идет об интеграции с облачным сервисом, например.

Совет с гуглением конечно дельный, но, поймите правильно, лучше разработчиков контроллер не знает никто. Поэтому и обратился к Вам, коллеги… Что касается драйвера, то нельзя ли подробнее. Какие варианты еще могут быть. Спасибо.

Теоретически это можно сделать в виде, например, отдельного модуля, который бы организовывал mqtt-бридж. Практически сейчас этого нет и в очереди разработки вряд ли появится в ближайшее время.

Сделать можно на любимом, желательно быстром, языке программирования: C, C++, Go. Физически mqtt-бридж отличается от обычного подключения клиента только одним битом в заголовке, поэтому кода там будет строчек 200 от силы.

1 лайк

Евгений, благодарю за ответ. Согласен, но вот в чем загвоздка. Желания у меня хоть отбавляй, а вто знаний пока не так много. Я учусь и разбираюсь. Но некоторые вещи для меня пока не так очевидны. Опыт программирования имеется. Тут без вопросов. Подскажите с чего можно начать разработку такого модуля. Что взять в качестве примера, если таковой имеется. Спасибо.

я собственно написал всё, что нужно, если опыт программирования у вас имеется. Выбирайте язык программирования, выбирайте библиотеку для MQTT для него, дальше делайте два клиента, одним подключайтесь к удалённому брокеру, другим - к локальному.

Благодарю, Евгений. Буду пробовать.

1 лайк

а как удалить это cron-правило?
например было раз в час, а теперь надо тоже самое делать раз в два часа. Получается, надо старое удалить, новое запустить. Не нашел ничего - как его удалить, этот крон…

https://help.ubuntu.ru/wiki/cron

А вообще, оттуда же

Редактирование текущего файла расписания (при первом запуске будет выведен список поддерживаемых текстовых редакторов):

crontab -e

дейсвительно, есть удаление, буду пробовать… не совсем понимаю синтаксис. Если не получится, обращусь за помощью. Я видел примеры как объявляется, но не понимаю как эту команду указать при закрытии.
Скажите, пожалуйста, а вообще эти cron стоит пользоваться? Ведь то же самое можно сделать и на таймерах, только там кода больше. Но зато знаю как)) Есть преимущества, кроме более, может, удобоваримого кода?

Я, возможно, не до конца уловил нить обсуждения, но на всякий случай хочу предупредить: cron-правила внутри движка правил и системный cron - это разные несвязанные вещи.

ну я то это не знаю… Мне нужно пользоваться таймерами. Таймерами и интервалами. надежно, без плясок. Мне не важно как они называются, но если будет конструкция, которая работает, я буду её использовать. Пусть даже через ж, но чтобы работала стабильно. Скажите, что и как нужно использовать? Нужны таймеры в правилах.