Проблема с правилом

Добрый день!
Ни с того ни с сего начала появляться ошибка

ECMAScript error: Error: error error (rc -100)
anon native strict preventsyield
clearTimeout /usr/share/wb-rules-system/scripts/lib.js:225
anon /etc/wb-rules/_onButtonPress.js:59 strict preventsyield
call native strict preventsyield
anon /usr/share/wb-rules-system/scripts/lib.js:173 preventsyield

Скрипт на который ругается давно не изменял и он корректно работал (это скрипт ранее выложенный здесь, на форуме, по обработке двойного и длинного нажатия кнопки):

Спойлер
(function () {
'use strict';

var ActionButtons = {};


/**
 * Function that identifies what kind of press was performed: single, double or long press;
 * and assigns an action for each type of press.
 *
 * @param  {string} trigger         -  Name of device and control in the following format: "<device>/<control>".
 * @param  {object} action          -  Defines actions to be taken for each type of button press.
 *                                  Key: "singlePress" or "doublePress" or "longPress" or "longRelease".
 *                                  Value: Object of the following structure {func: <function name>, prop: <array of parameters to be passed>}
 *                                  Example:
 *                                  {
 *                                      singlePress: {func: myFunc1, prop: ["wb-mr6c_1", "K1"]},
 *                                      doublePress: {func: myFunc2, prop: ["wb-mrgbw-d_2", "RGB", "255;177;85"]},
 *                                      longPress: {func: myFunc3, prop: []},
 *                                      longRelease: {func: myFunc4, prop: []}
 *                                  }
 * @param  {number} timeToNextPress -  Time (ms) after button up to wait for the next press before reseting the counter. Default is 300 ms.
 * @param  {number} timeOfLongPress -  Time (ms) after button down to be considered as as a long press. Default is 1000 ms (1 sec).
 */
ActionButtons.onButtonPress = function (trigger, action, timeToNextPress, timeOfLongPress) {
    var buttonPressedCounter = 0;
    var timerWaitNextShortPress = null;
    var timerLongPress = null;
    var isLongPress = false;

    var ruleName = "on_button_press_" + trigger.replace("/", "_");

    defineRule(ruleName, {
        whenChanged: trigger,
        then: function (newValue, devName, cellName) {

            // If button is pressed, wait for a long press
            if (newValue) {

                if (timerWaitNextShortPress) {
                    clearTimeout(timerWaitNextShortPress);
                }
                timerLongPress = setTimeout(function () {
                    if (typeof action.longPress === "object") {
                        if (typeof action.longPress.func === "function") {
                            action.longPress.func.apply(this, action.longPress.prop);
                        }
                    }
                    // log(">>>>>>> long press <<<<<<");
                    isLongPress = true;  // Long press identified, we will skip short press
                    buttonPressedCounter = 0;
                }, timeOfLongPress);

            }

            // If button is released, then it is not a "long press", start to count clicks
            else {
                if (!isLongPress) {
                    clearTimeout(timerLongPress);
                    buttonPressedCounter += 1;
                    timerWaitNextShortPress = setTimeout(function () {
                        switch (buttonPressedCounter) {
                        // Counter equals 1 - it's a single short press
                        case 1:
                            if (typeof action.singlePress === "object") {
                                if (typeof action.singlePress.func === "function") {
                                    action.singlePress.func.apply(this, action.singlePress.prop);
                                }
                            }
                            // log(">>>>>> short press - single <<<<<<");
                            break;
                        // Counter equals 2 - it's a double short press
                        case 2:
                            if (typeof action.doublePress === "object") {
                                if (typeof action.doublePress.func === "function") {
                                    action.doublePress.func.apply(this, action.doublePress.prop);
                                }
                            }
                            // log(">>>>>> short press - double <<<<<<");
                            break;

                       //***
                        case 3:
                            if (typeof action.triplePress === "object") {
                                if (typeof action.triplePress.func === "function") {
                                    action.triplePress.func.apply(this, action.triplePress.prop);
                                }
                            }
                            // log(">>>>>> short press - double <<<<<<");
                            break;
                        }                      
                      //**
                 
                      // Reset the counter
                        buttonPressedCounter = 0;
                    }, timeToNextPress);
                }

                // Catch button released after long press
                else {
                    if (typeof action.longRelease === "object") {
                        if (typeof action.longRelease.func === "function") {
                            if (typeof action.longRelease.prop === "array") {
                                action.longRelease.func.apply(this, action.longRelease.prop);
                            } else {
                                action.longRelease.func.apply(this, []);
                            }
                        }
                    }
                    isLongPress = false;
                }
            }

        }
    });
};



// export as Node module / AMD module / browser variable
if (typeof exports === 'object' && typeof module !== 'undefined') {
    module.exports = ActionButtons;
} else if (typeof define === 'function' && define.amd) {
    define(ActionButtons);
} else {
    global.ActionButtons = ActionButtons;
}

}());

ругается на строку 59, это:

clearTimeout(timerLongPress);

Еще в логе появляется ошибка

daemon.info wb-rules[3015]: ERROR: trying to stop unknown timer: <разное число>

Никаких обновлений не ставил…

Из того что заметил:

  • Если сделать двойное нажатие по конкретной кнопке, то только тогда вылезает ошибка ECMAScript, но реле срабатывает (на выключение это реле уже не срабатывает или срабатывает с задержкой в минуту)
  • После этого 2 независимых реле, подключенных по ModBus начинают хаотично включаться и выключаться в течении нескольких минут

Что это может быть и как диагностировать?

Складывается такое ощущение что после добавления двух WB-MR6C команды по modBus стали приходить запутанно и после включения диммера WB-MRGBW начинают включаться-выключаться на паре реле одного из новых WB-MR6C.
По RS-485 подключил последовательно 4 WB-MR6C и после них WB-MRGBW.

Как бы понять что происходит?

PS У меня модули WB-MR6LV/S но в интерфейсе добавлены как WB-MR6C. Это правильно?

Здравствуйте!
Пришлите, пожалуйста, архив с диагностической информацией контроллера. Опишите конфигурацию оборудования, что и куда подключено, чтобы можно было воспроизвести проблему. Как часто появляется данная ошибка правил?

Да, правильно.

В приведенном правиле у меня строка 59 это:

               if (!isLongPress) {

Сейчас в прошивках модулей реле появилась поддержка разных типов нажатий (короткого, длинного, двойного, короткого, а затем длинного), возможно вам это пригодится.

Складывается такое ощущение что после добавления двух WB-MR6C команды по modBus стали приходить запутанно и после включения диммера WB-MRGBW начинают включаться-выключаться на паре реле одного из новых WB-MR6C.
По RS-485 подключил последовательно 4 WB-MR6C и после них WB-MRGBW.

Как бы понять что происходит?

Нужен лог драйвера wb-mqtt-serial в момент появления проблем:

journalctl -u wb-mqtt-serial --since "10 minutes ago"

Добрый день!

Архив с конфигурацией во вложенииWB.rar (15.2 КБ)

Конфигурация: WB6 + 4х WB-MR6LV/S (2шт. старые, 2шт. только купил) + WB-MRGBW + модули расширения WBIO-DI-WD-14 (к нему и подключены кнопки) + WBIO-DO-R10R-4 + WBIO-DO-R10A-8

Все устройства ModBUS подключены последовательно в один порт RS-485 WB, а в реле провода в ходят в один клемник, а выходят к следующему реле из другого.

Как и где получить диагностическую информацию?

Проблема возникает всегда при двойном нажатии на кнопку “wb-gpio/EXT1_IN7” (правило описано в light_switches_rooms.js)

У меня в интерфейсе WB это следующая строка - clearTimeout(timerLongPress);

# journalctl -u wb-mqtt-serial --since "10 minutes ago"
-- No entries --

Предлагаю определить минимальный набор правил, при котором проблема воспроизводится, чтобы можно было воспроизвести проблему.
Как я понимаю, для обработки нажатий “wb-gpio/EXT1_IN7” нужны 2 правила: _onButtonPress и light_switch_rooms. При наличии только этих двух правил возникает ошибка?

Вы предлагаете удалить остальные правила?
Попробую

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

Странная у меня получилась ситуация.
Методом исключения я понял, что со всеми правилами все отрабатывает корректно, но только до тех пор пока да диммер (WB-MRGBW) не подается питание (он правда все равно мигает зеленым и виден как устройство т.к. питание для RS-485 подается отдельно).
Как только я подаю питание на БП светодиодной ленты и как следствие на сам диммер, вылетает ошибка

ECMAScript error: Error: error error (rc -100)
anon native strict preventsyield
clearTimeout /usr/share/wb-rules-system/scripts/lib.js:225
anon /etc/wb-rules/_onButtonPress.js:59 strict preventsyield
call native strict preventsyield
anon /usr/share/wb-rules-system/scripts/lib.js:173 preventsyield

Эта ошибка возникает тогда, когда таймер уже отработал, но для ID этого таймера вызывается функция clearTimeout. Чтобы ее устранить нужно в колбэк-функции в каждом таймере присваивать его (таймера) ID значение null, а перед вызовом clearTimeout проверять этот ID, что он не равен null. Но эта ошибка не должна бы быть критической.

Правильно ли я понимаю, что одно и то же правило нормально отрабатывает при отключенном питании ленты диммера (на клеммах + и - модуля) и выдает ошибку, когда это питание подано? При этом больше ничего не изменяется? Ошибка появляется только один раз или появляется при срабатывании какого-то конкретно правила (активации входа)?

можете привести пример как это правильно делать?

Ошибка возникает только при срабатывании правила, включающего летну через диммер и только тогда когда диммер запитан (клеммы + и -)

Хочу добавить, что проблема не только с этой ошибкой, но и с хаотичным включением/отключением других реле

Нет ли в сети устройств с одинаковыми адресами? Предлагаю пока отключить остальные устройства и решить проблему с диммером.

Вот это довольно странно, не должно быть связано. Ошибка возникает только один раз или каждый раз при срабатывании правила?

Отключите для теста физически остальные Modbus-модули и их опрос в конфигурации, оставьте только диммер.
Обновите ПО контроллера. Затем постарайтесь определить минимальный состав правил и функций в них, которые вызывают ошибку. Лишние правила и функции удалите, сделав резервную копию. Оставьте только те правила, которые участвуют в управлении диммером.

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

У меня только 5 modBUS устройств: 4 MR6LV и 1 WB-MRGBW
У них у всех точно разные адреса

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

Что это за информация, как ее собрать?
И есть инструкция по обновлению ПО контроллера? Она не затронет версию движка правил? (не хотелось бы его обновлять)

Попробую подключить диммер отдельно

Для примера:

dev["buzzer/enabled"] = true;
var timerLongPress = 0;



//в правиле делаем так
if (timerLongPress != 0) {
  clearTimeout(timerLongPress); 
}
timerLongPress = setTimeout(function () {
				dev["buzzer/enabled"] = false;
				timerLongPress = 0;
                }, 500);

Описано здесь: Веб-интерфейс Wiren Board — Wiren Board

Если у вас такого меню нет, то ПО контроллера довольно старое. В таком случае выполните команду в консоли:

dpkg -l

Весь вывод (он довольно длинный) команды пришлите в виде отдельного файла.

И есть инструкция по обновлению ПО контроллера? Она не затронет версию движка правил? (не хотелось бы его обновлять)
Да, инструкция здесь:
Обновление прошивки контроллера Wiren Board — Wiren Board

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

Попробовал подключить диммер ко второму порту RS-485 (на нем ничего больше не висит).
Ошибка выскакивать перестала, но реле (подключенные к первому порту RS-485) все равно хаотично переключаются после отработки правила.

dpkg.txt (67.3 КБ)

Довольно странно. Возможно, стоит попробовать запитать сам диммер и ленту от одного источника, если конечно питание ленты не превышает 28 В (V+ соединить с “+”, GND и “-” уже соединены внутри модуля).

При этом случайно не открыта страница Devices в веб-интерфейсе? Попробуйте закрыть браузер и проверить работу правил.

У вас очень старые версии ПО. Понимаю, что не хочется ничего менять и обновлять. Но, думаю, пытаться что-либо диагностировать и решать проблемы, которые уже вероятно решены в новых версиях, будет пустой тратой времени…

Какая у вас аппаратная версия контроллера?

WB6

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

это не помогло

Добрый день!
Обновил версии и у меня возникло несколько проблем, которые пока не понимаю как победить:

  1. возникает ошибка с обновлением mariadb
Спойлер
dpkg: error processing package mariadb-server-10.1 (--configure):
 subprocess installed post-installation script returned error exit status 1
dpkg: dependency problems prevent configuration of mariadb-server:
 mariadb-server depends on mariadb-server-10.1 (>= 10.1.48-0+deb9u2); however:
  Package mariadb-server-10.1 is not configured yet.

dpkg: error processing package mariadb-server (--configure):
 dependency problems - leaving unconfigured
Errors were encountered while processing:
 mariadb-server-10.1
 mariadb-server
E: Sub-process /usr/bin/dpkg returned an error code (1)
  1. в Настройках/Система пишет на кнопке “Сервис диагностики не доступен”
  2. у меня есть кнопка, подключенная ко входу W1. Раньше нажатие с нее обрабатывалось скриптом https://support.wirenboard.com/t/odnokratnoe-i-dlitelnoe-nazhatie-knopki-dlya-upravleniya-svetom/6939/22
    Сейчас получается так, что даже для срабатывания кнопки при одинарном нажатии требуется подержать ее дольше обычного (порядка секунды), а двойное нажатие вообще не распознается. Вроде как на входах модуля WBIO-DI-WD-14 все продолжает работать как и раньше.

Радует, что первоначальная проблема вроде как ушла - буду еще мониторить.