Пишу шаблон для modbus-устройства, которое в одном из выдает битовую маску своего состояния.
Формат регистра - 0 0 0 0 0 0 0 0 0 0 0 0 W X Y Z
Буквами обозначены биты, сигнализирующие о том или ином состоянии
Благодаря @my-wb обнаружил, что WB умеет каналы, читающие битовые маски из регистра modbus. Покопавшись на github-е нашел “описание” ( искать в коде “109:1:2”)
В результате у меня получился следующий шаблон:
Часть шаблона
…
{
“name”: “Fire”,
“reg_type”: “holding”,
“address”: “0x0012:0:1”,
“type”: “switch”,
“readonly”: true
},
{
“name”: “Bypass on”,
“reg_type”: “holding”,
“address”: “0x0012:1:1”,
“type”: “switch”,
“readonly”: true
},
{
“name”: “Bypass off”,
“reg_type”: “holding”,
“address”: “0x0012:2:1”,
“type”: “switch”,
“readonly”: true
},
{
“name”: “Defrosting”,
“reg_type”: “holding”,
“address”: “0x0012:3:1”,
“type”: “switch”,
“readonly”: true
}
…
И все вроде работает и отображается, НО wb-serial читает этот регистр 4 раза (для каждого канала индивидуально) 
А нет ли способа сделать более оптимально с одним единственным считыванием регистра и его разбором?
Сейчас нет, но можно прочитать регистр одним куском и распарсить его силами правил, например.
То есть создать еще одно устройство и его состояние отрабатывать правилами?
Можно добавить контрол к существующему.
Пример здесь.
1 Like
Написал следующий код в правилах:
var deviceName="rcs350p_11";
var controls=["Status FIRE", "Status Bypass On","Status Bypass Off", "Status Defrosting"];
if (!getDevice(deviceName)) log("device not present");
for (ctrl in controls) {
if (!getDevice(deviceName).isControlExists(controls[ctrl])) {
log("Adding ",ctrl, controls[ctrl], 1<<ctrl, Boolean(dev[deviceName+"/Fire-bypass-defrosting signal"]&1<<ctrl));
getDevice(deviceName).addControl(controls[ctrl], {
type: "switch",
value: Boolean(dev[deviceName+"/Fire-bypass-defrosting signal"]&1<<ctrl),
readonly: true
});
}
}
В логе пишет все абсолютно правильно, а контролы не добавляются. Что я делаю не так?
UPD: Поменял код так, чтобы вносить изменения в виртуальное устройство, а не устройство, заведенное с помощью template через настройки wb-mqtt-serial – код работает как надо. Значит ли это что добавлять контролы можно только в виртуальные устройства?
1 Like
Добавлять контролы можно к любым устрйоствам.
“виртуальное” или нет - определить можно так:
if (!getDevice(deviceName).isVirtual())
Воспроизведу, возможно на выходных.
У меня лично не получилось добавить контролы к не виртуальному устройству. А у вас?
Ну конечно получилось.
Вот только сегодня до компьютера добрался
Если брать мой пример реализации и проверить устрйство на “виртуальность”, как намекал выше - достаточно сделать так:
//05_10_test_01.js
var dashName = "wb-gpio";
var ctrlName = "cDate";
//Если устройство "не виртуально" - получим
//ERROR: Error in creating control cDate on device wb-gpio: Device is external
//Тут проверим, виртуальное ли устройство. Если нет - сделаем его таковым.
if (getDevice(dashName).isVirtual()){
log.info("Устройство",dashName, "вируальное")
}
else {
log.info("Устройство",dashName, "НЕ вируальное")
defineVirtualDevice(dashName, {
title: dashName,
cells: {},
});
}
//Тут проверим есть ли уже контрол и если нет - создадим.
if (!getDevice(dashName).isControlExists(ctrlName)) {
log.info("Контрола нет, создаем.")
getDevice(dashName).addControl(ctrlName, {
type: "text",
value: "",
readonly: true
});
}
//Тут сделаем таймер, котрый будет обновлять контрл
setInterval(function(){
dev[dashName][ctrlName] = (new Date()).toString();
log.info("timer fired", (new Date()).toString());
}, 1000);
Результат:

Ну и “виртуальность” - определяется, собственно топиками /devices/wb-gpio/meta/driver
и /devices/wb-gpio/meta
PS: вот благодаря таким вопросам работать интересно и увлекательно.
Благодарю!
PPS: А еще можно динамически контролы двигать, записывая разные занчения order 
1 Like
Видимо я что-то делаю не так 
Итак дано заведомо НЕ виртуальное устройство rcs350p_11
Делаю по Вашему образу и подобию код:
var deviceName="rcs350p_11";
if (getDevice(deviceName).isVirtual()){
log.info("Устройство",deviceName, "вируальное")
}
else {
log.info("Устройство",deviceName, "НЕ вируальное")
defineVirtualDevice(deviceName, {
title: deviceName,
cells: {},
});
}
И огребаю вот такую ошибку при его сохранении:
Script error: Error: Device with given ID already exists
/sbuild-nonexistent/go/pkg/mod/github.com/wirenboard/go-duktape@v0.0.0-20210723134114-881337fff8cb/api.go:124
anon native strict preventsyield
anon /etc/wb-rules/Ventilation-CTRL.js:78 preventsyield
То есть мне не дают, в отличии от Вас, создать виртуальное устройство с таким-же именем как и не виртуальное
Что я делаю не так?
UPD: Скопировал Ваш код 1-в-1. Такая же ошибка
Коллеги обратили внимание что я пользуюсь довольно грязным хаком, заменяя сервис-родитель.
В чем искренне раскаиваюсь.
Поэтому - предлагаю не добавлять топики в реальное (созданное и обслуживаемое не wb-rules) устройство. Такой хак может перестать работать вот в ближайшем релизе.
Все равно “пользовательский” интерфес - это виджеты, а в виджет можно собрать топики и из разных “устройств”.