Вопросы по структуре топиков WB MQTT

Добрый день!
Я пишу софт для управления умным домом голосом без интернета и использования внешних голосовых помощников, целевая платформа написанного софта Android/Windows/Linux. Сейчас приступаю к написанию парсера сообщений MQTT для поддержки оборудования WB, необходима помощь с данными для минимизации ошибок в написании парсера сообщений.

  1. Для получения списка оборудования в чате посоветовали подписаться на топик :
    /devices/+/meta
    Пример вывода:

Хотелось бы получить такого рода вывод с тестового стенда с максимальным списком оборудования WB.

  1. На сколько можно заложиться на поле … “title”: { “en”: DEVICE_TITLE, // English title of the device … для определения модели устройства. Так как в примере есть информация кроме названия устройства и возможно ли изменение этого поля пользователем?

  2. Так же интересуют максимальные примеры для топика /devices/+/controls/+/meta по оборудованию WB для написания парсера по контролам.

timeout 3 mosquitto_sub -t /devices/+/meta
{"driver":"wb-modbus","title":{"en":"WB-MWAC 11"}}
{"driver":"wb-modbus","title":{"en":"WB-MR3 36"}}
{"driver":"wb-modbus","title":{"en":"WB-MRWM2 74"}}
{"driver":"wb-modbus","title":{"en":"WB-MRWM2 21"}}
{"driver":"wb-adc","title":{"en":"ADCs"}}
{"driver":"wb-mqtt-knx"}
{"driver":"wb-w1","title":{"en":"1-wire Thermometers"}}
{"driver":"wb-modbus","title":{"en":"WB-MS v.2 41"}}
{"driver":"wb-modbus","title":{"en":"WB-MIR v2 55"}}

timeout 3 mosquitto_sub -v -t /devices/wb-mrwm2_21/meta 
/devices/wb-mrwm2_21/meta {"driver":"wb-modbus","title":{"en":"WB-MRWM2 21"}}

Меняю:


Теперь:

timeout 3 mosquitto_sub -v -t /devices/wb-mrwm2_21/meta 
/devices/wb-mrwm2_21/meta {"driver":"wb-modbus","title":{"en":"xxxxxx"}}

Точно так же можно поменять и остальные параметры, включая (автоматически) сформированный путь wb-mrwm2_21

Конструктор получается пластичный и нужно ориентироваться уже на конкретные доступные controls. Печально, что модель устройства в метаинформации жестко не зашита, было бы {“driver”:“wb-modbus”,“title”:{“en”:“WB-MWAC 11”}, “model”:“WB-MWAC”}, можно было бы отобразить у меня в интерфейсе картинку устройства.

А для чего, собственно?
Тут дело в том что взаимодействие (аппаратное) контролов внутри самого модуля определяется его настройками. То есть например может вход 1 - управлять выходом 1. А может управлять выходами 3 и 4, причем выход 3 будет переключаться а выход 4 - выключаться при каждом срабатывании. А может и никак не взаимодействовать с выхоами - предполагая программную обработку.
То есть модель, в общем - не сильно полезна.
Все на откуп проектировщику и наладчику.

Это понятно. Просто для UI составляющей процесса добавления устройства в моём ПО было бы красиво отображать иконку соответствующего железа. Но мне не на что завязаться, чтобы определить иконку устройства для отображения в UI.

Лучше выбор иконки отдать настройику. А еще могут быть совершенно произвольные устройства, например виртуальные или сторонние. Ну или zigbee, у которых контролы могут появляться -пропадать.

Есть иконки физических устройств, где я хотел именно отображать по модели реальные устройства. А есть пользовательские, которые отображаются в виджетах использования. Это разные экраны и это уже раздел UI/UX, который за мной, как за овнером создаваемого продукта.

{
// Control’s type
“type”: “value”,

// Units. ASCII string. Could be set only for type "value"
"units": "W",

// Maximum allowed control's value
"max": 100,

// Minimum allowed control's value
"min": -100.1,

// Control's value is rounded to defined precision by a driver and it is also used during user input validation
"precision": 0.1,

// Display order in user interface
"order": 10,

// The control doesn't have /on topic
"readonly": true,

"title": {
    "en": CONTROL_TITLE,    // English title of the control
    "ru": CONTROL_TITLE_RU, // Russian title of the control
    ...
}

}

А к этому есть примеры или четкие описания, что является опциональными параметрами, а что обязательными? Просто к примеру “units” опциональный и есть у типа “value”, а с другими вопрос, будет ли к примеру precision присутствовать в ответе для типа text? Просто при парсинге Json и маппинге его в объект это критичное знание.

Оно не проектировалось под такое — «устройства», это просто некие сущности и они не обязательно могут быть физическими, как сказал коллега.

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

Цель моего софта, сделать удобное приложение для панелек/планшетов на android для управления голосом и с экрана умным домом любой домохозяйкой. Форки это уже усложнение пользовательского опыта. Просто пока эту фитчу не будем делать, а потом может как-то и украсим физические устройства для удобства навигации в закладке настроек.

Тогда знание об устройствах в щите вообще довольно бесполезная информация - она нужна только на этапе ПНР и это делает точно не домохозяйка. Домохозяйке нужны понятные абстракции: люстра, сценарий, потеплее.

Конечно, это моё мнение.

1 лайк

А по этому пункту возможно получить ответ?

Повторно прошу ответить об опциональности полей в json объектах: https://github.com/wirenboard/conventions/blob/main/README.md#controlss-meta-topic

  1. Какие поля присутствуют обязательно во всех вариациях?
  2. Какие поля обязательно присутствуют при определенных установках в поле type?

Да, я сделаю. У нас явно в документации мало описания, потребуется для начала самому разобраться - а затем поправить ее.

1 лайк

В целом все поля опциональные. Сам топик /meta тоже может отсутствовать. Нет требований о том, что в зависимости от type обязательно должны быть какие-то поля. Но для некоторых типов только определённые параметры имеют смысл. Например, для rgb нет смысла в precision.

Думаю, что логика должна быть следующей.

  1. Проверить наличие типа в /meta, если его нет, то наличие топика /meta/type, если его тоже нет, то это тип text.
  2. Для типов составить список параметров, которые имеют смысл, и то, как интерпретировать их отсутствие.
  3. Прочитать доступные параметры из /meta и выбрать те, что имеют смысл согласно п.2. Если нет /meta, смотреть наличие /meta/min, /meta/max, /meta/order, /meta/readonly.

Сочетание п.2 и п.3 даст информацию об ограничениях и том, как стоит отобразить конкретный контрол.

1 лайк
  1. Поля. Очень плохо, что все поля по сути опциональны, как минимум одно поле “readonly” должно быть обязательным, чтобы мы, сторонние разработчики софта, знали можно ли писать в данное устройство или только читать. Для других типов, если поле опционально, то должно быть зафиксировано в типе дефолтные значение.
  2. Сам топик /meta тоже может отсутствовать. Для меня как разработчика стороннего софта, если топик отсутствует, то согласно конвенции оборудование не существует.

По мне, если производитель заявил конвенцию, то в своем оборудовании он должен её соблюдать. Сейчас основная причина проблем именно в несоблюдении конвенции самим производителем, я не говорю о легаси, а о сравнительно новых параметрах.
К примеру:

  1. В типе “range” заявлены только целочисленные параметры, а присылаются числа с плавающей запятой.
  2. Объявление явных параметров с целочисленными параметрами в оборудовании как тип с плавающей заятой. В примере ниже явно лучше было объявить range c min и max.

/devices/wb-mr6c_123/controls/Input 6 Single Press Counter/meta {“order”:13,“readonly”:true,“title”:{“ru”:“…”},“type”:“value”}
/devices/wb-mr6c_123/controls/Input 6 Long Press Counter/meta {“order”:14,“readonly”:true,“title”:{“ru”:“…”},“type”:“value”}

Парсер я написал, который думаю покроет сейчас 85% кейсов, но хотелось бы, что бы производитель по максимуму не отходил от своей же заявленной конвенции и привел значения в своих шаблонах к ней.

Еще одна из проблем, что в части сообщений которые и так UTF-8 названия повторно кодируются в UTF-8:

Message: MQTTMessage(topicName=/devices/wb-mr6c_123/controls/Input 5 Single Press Counter/meta, payload={"order":11,"readonly":true,"title":{"ru":"\u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u043d\u0430\u0436\u0430\u0442\u0438\u0439 \u0432\u0445\u043e\u0434\u0430 5"},"type":"value"}, retain=true)

Кто-то где-то что-то явно перемудрил. Так как кодируются и en и ru названия, а где-то не кодируются и передается нормально.

перепроверил в текущем testing - именно двйной не нашел, как воспроизвести?

Если работать с JSON-строками, как с объектами, то нет никакой проблемы кодировки. Да и перекодировки строк там нет — это сериализация так работает.

Вот пример разбора вашего сообщения на JS, можно запустить как правило на wb-rules:

// Строка из MQTT
var str = '{"order":11,"readonly":true,"title":{"ru":"\u0421\u0447\u0435\u0442\u0447\u0438\u043a \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u043d\u0430\u0436\u0430\u0442\u0438\u0439 \u0432\u0445\u043e\u0434\u0430 5"}}'

// Парсим в объект
var obj = JSON.parse(str)

// Выводим title
log(obj.title.ru)

Вывод:

2023-12-12 14:57:20 Счетчик коротких нажатий входа 5

Я говорю о двойной, так как получаемая строка из MQTT брокера сама по себе уже является строкой в кодировке UTF-8. А внутри неё опять происходит кодировка одного из параметров в UTF-8. Причем такому двойному кодированию (сериализации) подвержены не все русскоязычные строки, которые имеются в брокере от оборудования Wirenboard.