Непонятное поведение при перезапуске или сохранении WB-RULES и не только

При перезапуске правил из консоли в окне отладки веб-интерфейса появляются сообщения:

2023-03-22 08:55:07using file /var/lib/wirenboard/wbrules-persistent.db for persistent DB
2023-03-22 08:55:09error running command callback for /bin/sh: Error: error error (rc -100)
anon native strict preventsyield
init /usr/share/wb-rules-system/rules/wb-mqtt-dac.js:14
anon /usr/share/wb-rules-system/rules/wb-mqtt-dac.js:77
anon /usr/share/wb-rules-system/scripts/lib.js:339 preventsyield

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

2023-03-22 08:54:37Переменная white_square равна - -2
2023-03-22 08:54:41Переменная white_square равна - -3

в моем файле:

var white_square = 0 // Объявляем переменную (счетчик) - "white_square" и присваиваем ей значение - "0".

Помимо этого реле, которые управляются со входов, настроенных на режим mapping-матрицы для кнопок “не хотят забывать” настройки, которые я поменял и помимо новых действий по включению и отключению каналов, выполняют действия, которые были назначены ранее, но уже изменены.

Контроллер Wiren Board 7.3.4 (s/n AWLSAZTP), release wb-2304 (as testing)
Linux wirenboard-AWLSAZTP 5.10.35-wb133 #1 SMP Tue Feb 21 08:14:01 UTC 2023 armv7l GNU/Linux

Прошу помочь разобраться со всем этим.

Добрый день.

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

Ок. Попробую по порядку.

  1. Имеется правило для включения/выключения блока питания в зависимости от того, включена или нет его нагрузка. Для этого объявляется переменная-счетчик white_square и ей присваивается значение 0. Далее по условию включается/остается включенным/выключается реле wb-mr6cu_105/K1
var white_square = 0
defineRule("rampPowerSupply1", {
  whenChanged: ["wb-led_21/Channel 1", "wb-led_21/Channel 2", "wb-led_21/Channel 3", "wb-led_21/Channel 4"],
  then: function(newValue, devName, cellName) {
    if (newValue == 1) {
      ++white_square;
      log("Переменная white_square равна -", white_square)
      dev["wb-mr6cu_105/K1"] = newValue;
    } else
    --white_square;
    log("Переменная white_square равна -", white_square)
    if (white_square == 0) {
      dev["wb-mr6cu_105/K1"] = newValue;
    }
  }
});

Если из терминала произвести рестарт wb-rules в окне отладки появляются следующие предупреждения:


но иногда еще и значение переменной white_square и оно может оказаться, например, отрицательным - минус 1, или минус 3. Сейчас мне не удалось воспроизвести данную ошибку, но она периодически возникает.
Если зайти в настройки драйвера serial-устройств /etc/wb-mqtt-serial.conf, сделать и записать какие-либо изменения конфигурации, то в окне отладки возникают подобные предупреждения:

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

Какого результата я ожидаю? Что объявленная в правилах переменная будет иметь значение, которое ей задано и менять его будет во время выполнения правила в соответствии с заданными условиями.
Пошел готовить ответ по следующей проблеме, чтобы как то разделить и не перепутать.

А если на момент запуска нет контрола или вернется null?

То есть правило несколько раз срабатывает?
Опубликуйте пустое значение для проверки.

Естественно, ведь контрол не существует.

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

А можно для дилетанта поподробнее? А то я не “догоняю” как такое возможно.

Не знаю, возможно срабатывает несколько раз или как-либо еще. Та же просьба. Растолкуйте какое пустое значение опубликовать и где?

Так? Или как?

var white_square = 0
log("Переменная white_square равна -", white_square)
defineRule("rampPowerSupply1", {

К слову, удалось воссоздать момент, когда переменные улетают в отрицательные значения при записи изменений в конфигурацию.

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

Пробовал читать когда объявленная переменная возвращает null и окончательно запутался. И я просмотрел информацию о том, как выполняются правила, но тоже по-моему запутался. Как тогда переменные объявлять? И, если правило может спонтанно выполниться не полностью или откуда-нибудь с середины, то как избежать ошибки? Куда копать хотя бы?

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

  1. я правильно понимаю, что какой-либо строгой системы просмотра и выполнения правил здесь “поймать” не получится и нужно просто воспринимать это, как данность и исходить из этого?
  2. я правильно понимаю, что все эти явления будут происходить, пока я не настрою окончательно все то, что настраиваю и в дальнейшем, если отследить, что переменная установлена корректно и после ничего не менять, то есть - контроллер и конфиги не “дергать” - правила не будут вызываться так, как это при настройках происходит? А то смущает строка, касательно таймеров, которые инициируют избирательный просмотр правил. Например, если таймеры запускаются из одного правила, то это может или не может вызвать просмотр другого правила?

При написании нужно учитывать и “невероятные” значения и отсекать их.

Какждое применение изменений конфигов, например того же wb-mqtt-serial вызывает удаление (очистку) топиков устройств и создание их снова.,
Таймеры инициируеют просмотр правил в которых используется триггер asSoonAs/

Ок. Тогда значит мне нужно проверять а) существует ли контрол в момент выполения правила, на него ссылающегося, а также б) проверять значение на != null, undefined и т.п.?
Где это лежит, куда смотреть? В топиках mqtt? var i = “Прошу прощения если туплю”

Вопрос еще: если я проверил и контрол не существует или значение равно null, то что мне делать? Выключать правило, чтобы оно перестало выполняться или как реагировать? log(i)

Вы в своем правиле анализируете устройство wb-led_21 и управляете устройством wb-mr6cu_105. Соответственно, эти устройства должны быть сконфигурированы (в настройках wb-mqtt-serial, если устройство подключено по Modbus). Драйвер создает топики “wb-led_21/Channel 1”, “wb-mr6cu_105/Kx”… Движок правил wb-rules при рестарте видит эти топики в вашем правиле, и подписывается на них. Если в момент старта wb-rules этих топиков нет - будет ошибка. И, кстати, откуда вы взяли “wb-led_21/Channel 1”? У WB-LED есть “wb-led_21/Channel 4”, Channel 1, 2, 3 нет.
Проверять контролы в скрипте на существование не надо - ошибки при записи файла с правилом сразу скажут вам о том, что контрола нет. Вопрос в том, почему у вас этого контрола нет.

Ну, вроде как настроены, подключены и в MQTT присутствуют, судя по картинке. Или я чего-то не понимаю?
При сохранении правила ошибок не появляются.

Вы хотите сказать, что при выполнении вот этого:

whenChanged: ["wb-led_21/Channel 1", "wb-led_21/Channel 2", "wb-led_21/Channel 3", "wb-led_21/Channel 4"], // Получаем значение контрола и
    then: function(newValue, devName, cellName) { // передаем его в then функцию. Затем

я всегда буду получать значения только 4-го канала? Вроде бы должно быть значение того элемента массива, который привел к срабатыванию whenChanged?

Так в том и дело, что никаких ошибок при записи файла с правилом не возникает. Все ровненько. Более того, правило корректно отрабатывает, пока не происходит обращения к нему в результате каких-либо действий, вроде изменения конфигурации, причем не тех устройств, которые упоминаются в правиле, а любых прочих.

не понял сразу, что он у вас в другом режиме работает

А, да, сорри, наверное мне самому сразу стоило указать, что все led-диммеры у меня работают в режиме W+W+W+W.

мне кажется, не имеет смысла использовать счетчик, можно просто при появлении нового значения любого из Channel_x использовать конструкцию:

dev["wb-mr6cu_105/K1"] = (dev["wb-led_21/Channel 1"] || dev["wb-led_21/Channel 2"] || dev["wb-led_21/Channel 3"] || dev["wb-led_21/Channel 4"])

Изменения конфигурации, как и рестарт wb-rules, не могут изменять объявленную вами переменную, если код написан корректно. Если говорить о вашем коде, то при рестарте wb-rules состояние вашего счетчика может стать отрицательным. Например, если рестарт произошел при включенных каналах - ваша переменная в момент старта скрипта обнуляется, после выключения первого же канала она станет отрицательной.
И не используйте

if (newValue == 1)

в вашем случае newValue - булево, надо так:

if (newValue == true)
или
if (newValue)

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

Именно так и происходило. В отладке появлялись именно отрицательные значения.

Постараюсь запомнить, еще раз большое спасибо.

Эта тема была автоматически закрыта через 7 дней после последнего ответа. В ней больше нельзя отвечать.