Ошибка в wb-rule (свести два канала счетчика в 1) - прошу помощи

  1. Я только учусь (точнее, пытаюсь разобраться “как оно работает”, вот только делать это приходится на живых задачах и в условиях дефицита времени. Так что прошу снисхождения и подсказок.

  2. Задача такая: имеется счетчик WB-MAP12E в режиме амперметра и кабельная линия “в две нитки” (причем параллельно соединенные кабели разной длины, а один, похоже, еще и поврежден - из-за чего токи по ним не равны, а в одной из фаз меняются непропорционально друг другу). В результате трансформаторы каналов 3 и 4 повешены отдельно на каждую “нитку”, но выводить токи и сохранять историю надо как один канал (то есть суммировать по фазам).

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

  4. А вот это самое печальное:
    Виртуальное устройство в списке доступных для виджета не появляется (или не должно?),
    добавление его в JSON виджета ошибки не вызывает, но все значения - NaN,
    При этом в истории каналы виртуальный девайс появляется, вот только “нет записей для отображения”.
    В логах все тихо и спокойно:
    |28-06-2024 20:53:43.420|INFO: reloading file: /etc/wb-rules/summator34.js|
    |28-06-2024 20:51:25.686|INFO: reloading file: /etc/wb-rules/summator34.js|
    |28-06-2024 20:31:27.058|INFO: reloading file: /etc/wb-rules/summator34.js|

5. Прошу помочь с корректным кодом.

summator34.js (2,4 КБ)

Добрый день.
Пришлите файл скрипта архивом.

В файле два варианта правила. Перед проверкой один надо удалить (или закомментить).
Плюс для разных фаз пробовал записать правило по-разному - не помогло, но оставил в скриптах.

summator34.zip (730 байтов)

Есть ли ошибки при сохранении вашего правила?

Не понимаю, что здесь конкретно делаете. Опишите подробнее.
Напоминаю, что мы не пишем скрипты. Для этого можете обратиться к нашим партнерам.

Нет, ни одной ошибки не появляется. В том-то и проблема: были бы ошибки - было бы понятно, куда копать.

Что конкретно делаю:

  1. определяю константы с названиями устройств (для подстановки при вызове) и промежуточную переменную.
  2. создаю виртуальное устройство (с форматом как у счетчика), чтобы иметь возможность регистрировать данные стандартными средствами. Параметры виртуального устройства в списке наблюдаемых параметров настроек истории появляются.
  3. создаю правила (отдельно на каждую фазу), которые:
  • выполняются в случае изменения параметра Irms соответствующей фазы в канале 3 или 4 (пробовал и объединяя два параметра квадратными скобками, как у вас в описании нашел; также пробовал проверять только один параметр, как в ваших примерах - результат не отличается),
  • берут значение Irms изменившейся фазы каналов 3 и 4 и записывают их сумму в параметр Irms виртуального устройства.
    Всё.

Иногда (ключевое - иногда!) редактор правил подсвечивает в условии whenChanged строку
then: function (newValue, devName, cellName) {
как ошибку, иногда не подсвечивает (логику не понял, можно просто два раза подряд открыть правило в редакторе и нажать “сохранить” - один раз покажет ошибку в этой строке, второй не покажет).
“Методом тыка” установлено, что если суммировать значения Irms в промежуточную переменную, а потом её записывать в виртуальное устройство - ошибки не возникает.
Вот только на выходе - в виртуальном устройстве всё равно NaN (а ведь даже в определении виртуального устройства явно заданы value - то есть параметр не должен быть пустым!).
В силу того, что у вас отсутствует описание устройств, отсутствует описание формата JSON, отсутствует описание правил формирование rules (только отдельные фрагменты, причем на максимально простых задачах) - я вынужден обращаться на форум, чтобы разобраться, какое из не описанных нигде требований к формату/командам/параметрам движка правил мной нарушено, и что именно привело к неработоспособности созданных rule.

P.S.
//Вы опять даете ссылку на продавцов совместимого оборудования и scada вместо ссылки на интеграторов.// ,был не прав, просто не долистывал ниже…
Впрочем, обе найденных мной фирмы, работающих с вашим оборудованием - уже отказались заниматься моими задачами (аргументировав что они слишком простые и не дают коммерческого интереса, даже если задрать цены). одна из них, кстати, из вашего списка интеграторов.
Упс?

Странно. Закидываю вами присланный файл и сразу это:


Пришлите файл без ошибок, иначе так будем смотреть очень долго.

Пришлите диагностический архив.

Покажите, какую ошибку показывает.

Подпишитесь на данный топик и покажите результат.

Опишите подробнее какой информации не хватает. Из контекста я не понял.

Это формат обмена данными. По нему в интернете очень много всего зачем нам его дублировать. Какое описание JSON вы ожидаете увидеть в нашей документации?

Чего вам не хватает из данной документации в понимании работы с wb-rules?

Упс. Прошу прощения за спешку, был не прав…
Во избежание ошибки скачал с контроллера (будет заведомо то, что сейчас крутится и не выдает ни одной ошибки):
summator34_WB7downloaded.zip (554 байта)

Пришлите архив.

Покажите результат.

Первое, что вижу, что ваше правило (“summator”) скорее всего не выполняется.

  1. if (newValue=true) - используете некорректный оператор сравнения. Посмотрите пример из документации, как использовать условный оператор.
  2. if (newValue=true) - в этом же месте видимо пытаетесь проверить равно ли newValue true или нет. Но в данном случае я ожидаю, что newValue не булевская переменная.
  3. Irms_Summ = deviceSource+‘/Ch 3 Irms L1’ + deviceSource+‘/Ch 4 Irms L1’; - переменной, которую хотите использовать для суммы токов, зачем-то присваиваете строку.

Данный скрипт не будет работать как описана задача.

Пока я вижу некорректный код на JavaScript без привязки к нашему контроллеру.

  1. Вложено
    log_20240701T114143 (1).zip (1,3 КБ)

  2. Не удалось повторить на 11 попытках (я перезапустил контроллер). Сейчас ошибок не выдает.

  3. я подписан на данный топик (прилетают уведомления на почту).

  4. сам формат описывает только структуру объекта, и это, действительно, повторять не стоит. Вот только параметры объектов у каждой реализации свои (включая вашу). Вот только мне нигде не удалось найти, какие из параметров, перечисленных в описании объекта (наверное, они есть. по крайней мере ваши коллеги меня в этом убедили), являются обязательными (это было в прошлой проблеме - причем даже у ваших коллег ушло больше 2 недель на выявление того факта, что я не указал обязательного параметра, отсутствие которого не вызывало ошибку в виджете, но напрочь подвешивало историю). Аналогично, мне не удалось найти какие параметры могут применяться с конкретным типом данных (например, что условие “read-only” в описание параметра применимо только к булевым значениям). Также не удалось найти ограничения ваших внутренних форматов (например, формат current мне не удалось найти в описании ECMAScript).

  5. Не хватает (либо мне не удалось найти) описания/примера, как:

  • проверять изменение параметра хотя бы в одной из нескольких телеграмм mqtt одним правилом;
  • суммировать значения параметров из нескольких телеграмм (особенно учитывая не описанный в ECMAScript формат параметра)
  • вносить полученное выше значение в параметр виртуального устройства (вот это найти удалось в примерах для другого утройства. Вот только у меня нет уверенности, что для виртуальных и реальных девайсов механизм работает одинаково - но допустим).
  • как отображать параметры виртуального устройства в виджете (в списке устройств и параметров для виджета виртуальное устройство не появляется. Хотя на вкладке истории они есть).

Спасибо за предметный разговор.

Мне он вообще не нужен. Но если вводить сразу команду (любую, вплоть до dev[‘buzzer/enabled’] = true;) - в предшествующей строке “then…” возникает ошибка.

  1. Спасибо. Глаз замылился, пока не показали - не увидел, что пропущено второе “=” (я в курсе, что в операции сравнения должно быть “==”. Но увы).
  2. А вот это самое интересное. В пятницу выяснил, что значение NewValue почему-то булевое (я ожидал, что будет изменившийся параметр - но нет, выходит true или false). Хотелось бы понять в чем ошибка.

Так… А вот это, похоже, вторая причина. Мне нужно значение параметра WB-MAP12E_32/Ch 3 Irms L1 (объявлено, что deviceSource = “WB-MAP12E_32”). А ведь я взял такой формат из примера на вашем сайте, только названия устройств подправил!

UPD
Интересное: после исправления условия в if (поставил NewValue!=0, это вроде как должно работать и на булевых и на числовых форматах, во всяком случае к ошибке не привело) - виртуальное устройство появилось в списке параметров для виджетов (а не только в истории).
Интересная взаимосвязь. Неожиданная для меня.

Вот в таком виде - правило почти заработало:

defineRule("summator", {
 whenChanged: [deviceSource+'/Ch 3 Irms L3'],
  then: function (newValue, devName, cellName) {
    log("newValue=" + newValue);
    nIrms = Number(dev[deviceSource+'/Ch 4 Irms L3'])
    log("Irms(1)=" + nIrms);
    nIrms = +nIrms + +newValue
    log("Irms(sum)=" + nIrms);
    nIrms = Math.round(nIrms * 10000) / 10000;
    log("Irms(round)=" + nIrms);
    sIrms = String(nIrms)
    dev[deviceDestination+'/Ch 34 Irms L3'] = nIrms;
    log(dev[deviceDestination+'/Ch 34 Irms L3']);
  }
});

Почти - потому что лог выглядит вот так:

|01-07-2024 14:11:42.087 [wb-rules]|INFO: [rule info] NaN|
|01-07-2024 14:11:42.086 [wb-rules]|ERROR: control wb-map12e_32_sum/Ch 34 Irms L3 SetValue() error: can't convert control value '207.6981' (type float64) to datatype '0'|
|01-07-2024 14:11:42.085 [wb-rules]|INFO: [rule info] Irms(round)=207.6981|
|01-07-2024 14:11:42.084 [wb-rules]|INFO: [rule info] Irms(sum)=207.69810000000002
|01-07-2024 14:11:42.083 [wb-rules]|INFO: [rule info] Irms(1)=103.2764|
|01-07-2024 14:11:42.080 [wb-rules]|INFO: [rule info] newValue=104.4217|

То есть, очевидно, что с вашими замечаниями мне удалось добиться работоспособности скрипта, однако:

  1. в условии whenChanged можно указывать только один проверяемый параметр (при том, что у вас в описании условия показаны несколько параметров через запятую).
  2. если виртуальному устройству задать параметр с типом “current” - записать в него какое-либо значения становится невозможным (см. на ошибку конвертации в логе)?
  3. типу “current” соответствует datatype 0. Что это за тип данных (описания ни на гитхабе, ни на сайте поиск не дает) - и, главное, как в него конвертировать значение типа Float64, который используется для резкльтатов математических вычислений?

Ограничения wb-rules, о которых не удалось найти информацию:

  1. Тип данных “current” (ток) - текстовый.

  2. Если в одном правиле несколько условий срабатывания - обрабатывается только последнее условие.

  3. В условии whenChanged возможен контроль изменения только одного параметра (хотя в описании на сайте - показаны два через запятую).

  4. Техподдержка либо абсолютно уверена, что любой покупатель оборудования обладает знаниями сотрудника WB (у покупателя же нет своей работы и есть доступ ко внутренним документам WB), либо сами не знают вышенаписанного (в последнее верить не хочется).
    :sleepy:

тип - deprecated GitHub - wirenboard/conventions: Wiren Board MQTT Conventions

quote=“ailcat, post:13, topic:20775”]

 whenChanged: [deviceSource+'/Ch 3 Irms L3'],

[/quote]
Мне непонятно зачем тут используете перечисление, когда в документации подробнейшим образом расписано.

Приведите пожалуйста пример. Я сомневаюсь в наличии такого бага.

Тоже прошу пример.

Техподдержка пользуется той же документацией.

  1. Попытка присвоить параметру с типом current (из описания, взятого в документации на wb-map12e, которое полностью бьется с приведенной таблицей) результат выполнения бинарного сложения приводит к ошибке:
    01-07-2024 15:02:12.088 ERROR: control wb-map12e_32_sum/Ch 34 Irms L3 SetValue() error: can't convert control value '206.6131' (type float64) to datatype '0'
    Передача этого же значения в виде String(nIrms), где nIrms=206.6131, обрабатывается корректно (и это вообще единственный вариант, который приводит к передаче значения в параметр виртуального устройства. Испробованные десятки вариантов с явной и неявной конверсией приводили либо к упомянутой ошибке движка правил, либо к NaN вместо значения параметра).

  2. Не совсем понял, о каком перечислении идет речь. Если о том, что отслеживаемый параметр взят в квадратные скобки, то… Вы не поверите - это единственный способ отслеживать изменение параметра, не приводящий к ошибке и реагирующий на изменение значения. Задание единственного условия без квадратных скобок либо передавало в newValue дважды сконкатенированное значение переменной deviceSource (которое на самом деле ссылка на объект), либо приводило к ошибке на этапе записи макроса в редакторе правил веб-интерфейса.
    01-07-2024 14:58:00.082 INFO: [rule info] newValue=wb-map12e_32wb-map12e_32/Ch 4 Irms L3
    Равно и описать два параметра через запятую, как написано в упомянутой вами “подробной документации”, давало такой же результат или ошибку.

  3. Вот текущее (работающее) правило: summator34.zip (581 байт).
    Так вот, оно работает только в таком виде (шесть правил на шесть проверяемых параметров). Если внести все whenChanged внутрь одного правила - будет обработано только последнее условие, хотя все условия будут полной копипастой, в которой меняются только “L1”, “L2” и “L3” в названии параметра (выявлено по маркерам в логах. Извините, влом лопатить тысячи их строк, чтоб найти следы - если для вас это важно, можете попробовать воспроизвести проблему у себя).
    Если в перечислении внутри whenChanged попробовать проверить два параметра (для Ch3 и Ch4) - будет либо конкатенация текста ссылки на объекты (вместо проверки изменения параметров объектов), либо ошибка, либо ошибка из-за конкатенации.

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

P.S.
Да, использование вашего оборудования нешаблонным способом уберегло от дорогостоящей ошибки (несравнимой со стоимостью оборудования и моих 2 рабочих дней).
Но при наличии нормальной документации вместо 2 дней (львиная доля которых была потрачена на попытки разобраться “да какого лешего оно не работает как написано в найденном”) можно было решить задачу за 2 часа, даже набивая скрипт одним пальцем.

Проверяю.
Screenshot_20240702_171113

Код для проверки:

//07_02_test_03.js

function makeNewVirtualControl(vdName, nameControl, typeControl){
  if (getDevice(vdName) === undefined) {
    defineVirtualDevice(vdName, {
      title: vdName,
      cells: {},
    })
  }
     //Тут проверим есть ли уже контрол и если нет - создадим.
    if (!getDevice(vdName).isControlExists(nameControl)) {
      getDevice(vdName).addControl(nameControl, typeControl);
    }
}

makeNewVirtualControl("currentForTest", "currentValue", {type: "current", value: 0, readonly: false}); 


setTimeout(function () {
  log.info("Тип значения", typeof(dev["currentForTest/currentValue"]), "значение:", dev["currentForTest/currentValue"]);
  dev["currentForTest/currentValue"] = 100+20;
  //ожидаю изменение на 120
  log.info("Тип значения", typeof(dev["currentForTest/currentValue"]), "значение:", dev["currentForTest/currentValue"]);
  dev["currentForTest/currentValue"] = "333";
  log.info("Тип значения", typeof(dev["currentForTest/currentValue"]), "значение:", dev["currentForTest/currentValue"]);
}, 200);

И вывод:

2024-07-02 17:31:32Тип значения string значение: 0

2024-07-02 17:31:32Тип значения string значение: 0

2024-07-02 17:31:32Тип значения string значение: 333

Что ж, стыдно. Оформлю багу.

Ну вот он пример, который пишут пользователи.
Перепроверил документацию - все верно.

Где?

Один топик: Мастер переключатель на кнопку без фиксации - #2 от пользователя Flox
несколько топиков : Астрономическое реле по прогнозу погоды - #11 от пользователя KornilovIV
Еще ни у кого не было похожих проблем.