Создание виртуального устройства средствами web ui

Добрый день!
Возникла необходимость создавать виртуальные устройства автоматически, решил использовать для этого средства WEB UI. Сделал следующую функцию:

$rootScope.defineVirtualDevice = function(name, type, value) { mqttClient.send('/devices/' + name + '/meta/name', name); mqttClient.send('/devices/' + name + '/controls/enabled', value); mqttClient.send('/devices/' + name + '/controls/enabled/meta/type', type); mqttClient.send('/devices/' + name + '/controls/enabled/meta/order', '1'); };

Устройство успешно создаётся, но при переключении ведёт себя не так, как созданное через движок правил.

Пример:

Работа устройства созданного через движок правил
root@wirenboard:~# mosquitto_sub -v -t '/devices/switch_script_air_humidity3/#' /devices/switch_script_air_humidity3/meta/name Switch script /devices/switch_script_air_humidity3/controls/enabled 0 /devices/switch_script_air_humidity3/controls/enabled/meta/type switch /devices/switch_script_air_humidity3/controls/enabled/meta/order 1 /devices/switch_script_air_humidity3/controls/enabled/on 1 /devices/switch_script_air_humidity3/controls/enabled 1 /devices/switch_script_air_humidity3/controls/enabled/on 0 /devices/switch_script_air_humidity3/controls/enabled 0

Работа устройства созданного через веб-интерфейс:
root@wirenboard:~# mosquitto_sub -v -t '/devices/air_humidity_rule1/#' /devices/air_humidity_rule1/meta/name air_humidity_rule1 /devices/air_humidity_rule1/controls/enabled 0 /devices/air_humidity_rule1/controls/enabled/meta/type switch /devices/air_humidity_rule1/controls/enabled/meta/order 1 /devices/air_humidity_rule1/controls/enabled/on 1 /devices/air_humidity_rule1/controls/enabled/on 0

Как видно, при переключении, у второго устройства публикуется только /enabled/on топик, а /enabled не публикуется.
Процесс переключения в обоих случаях происходит одинаково, поэтому думаю, что проблема в виртуальном устройстве.

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

Доброго времени,

Движок правил при создании виртуального устройства не только публикует все перечисленные топики в MQTT, но ещё и подписывается на топики /devices/_devname/controls/_ctrlname/on для всех контролов этого витруального устройства. Когда в этот топик что-то публикуют, движок правил реагирует на это по подписке и публикует значение уже непосредственно в /devices/_devname/controls/_ctrlname.

Это общий механизм конвенции, которой следуют все сервисы Wiren Board. Сделано это для того, чтобы:

  • игнорировать некорректные значения, полученные от клиентов;
  • отражать реальное положение дел (например, устройство соответствует релейному модулю, тогда получение сообщения c топиком .../on даст команду на переключение реле, а топик самого контрола продолжит показывать реальное состояние реле).

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

1 Like

Спасибо за ответ!
Попробовал решить проблему публикацией в оба топика ( с /on и без). При запущенном mosquitto_sub стало видно, что изменения в этих топиках успешно произошли, так же изменения пришли в веб-интерфейс.
Однако, при перезапуске mosquitto_sub значения сбросились, то же самое произошло при перезагрузке интерфейса, всё сбросилось на 0.
Не могу понять, почему опубликованные значения сбрасываются?
Это происходит и с другими топиками, не только виртуальными устройствами. Публиковать пробовал и через консоль и через веб-интерфейс, всё равно происходит сброс.

Это происходит из-за того, что вы не ставите флаг retain для сообщений. По умолчанию сообщения рассылаются только в момент его публикации, после чего благополучно забываются брокером. Если поставить флаг retain, брокер его запомнит и будет рассылать последнее сообщение из топика при подписке.

В web UI для этого нужно дописать аргумент в вызов метода send. Вообще, полный список аргументов там такой:

mqttClient.send(topic, message, retain, qos);

Нам нужно выставить retain в true, то есть вызов должен выглядеть вот так:

mqttClient.send('/devices/' + name + '/meta/name', name, true);

Все сервисы Wirenboard по умолчанию публикуют все сообщения устройств с флагом retain и QoS 1. Исключение составляют сообщения, которые публикуются в /on-топики, там флаг retain ставить не нужно.

1 Like