Движок правил: примеры кода

Покажите какие значения внесли.

Выложу целиком:

 var Thermometer = "wb-w1/28-00000b0ff412"; // Здесь указать свой датчик
 var relay_on_timer_id = null;
 var relay_off_timer_id = null;
 var temp_on = -3;  // Указать свою температуру
 var temp_off = -1; // Указать свою температуру
 
 defineVirtualDevice ("upravl_heating_skvazin", {
  	title: "Upravl obogrev skvazin-drenaz",
  		cells: {
    		  enabled: {
     	    type: "switch",
     	    value: false,
           },
   }
 });
 
function on_timer() {    
  //log.info("in function on_timer()");
dev["wb-gpio"]["EXT3_R3A1"] = true; //Здесть указать имя своего модуля,установи модуля wb-gpio в состояние "включено"
dev["wb-gpio"]["EXT3_R3A2"] = true; //Здесть указать имя своего модуля установи модуля wb-gpio в состояние "включено"
   relay_on_timer_id = setTimeout(function() {
      off_timer();
   }, 10000); //для теста 10 сек во включенном положении, 2 часа это будет 2*60*60*1000       
   log.info("Relay skvaz ON, Wait 2ch");
  }
      
 function off_timer() {
  // log.info("in function off_timer()");
   dev["wb-gpio"]["EXT3_R3A1"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
  dev["wb-gpio"]["EXT3_R3A2"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
   relay_off_timer_id = setTimeout(function() {
      on_timer();
   }, 40000); //для теста 30 сек в выключенном положении, 4 часа это будет 4*60*60*1000
  log.info("Relay skvaz OFF, Wait 4ch");
 }
 
 function Stop_Timer(){
   //log.info("Timer stop");
   if (relay_on_timer_id)  {relay_on_timer_id = clearTimeout(relay_on_timer_id); };  
   if (relay_off_timer_id) {relay_off_timer_id = clearTimeout(relay_off_timer_id); }; 
 }
   
     defineRule("rule upravl heating skvazin", { //название правила - “контроль обогрева скважины”
        whenChanged: Thermometer, //при изменении состояния датчика wb-w1/28-00000b0ff412
         then: function(newValue, devName, cellName) { //выполняй следующие действия          
             if (dev.upravl_heating_skvazin.enabled) { // если вируальн. устр-во в положении enabled
               //log.info("if dev.upravl_heating_skvazin.enabled = true");
                 if (newValue < temp_on) { //если температура датчика меньше xx градусов
                     on_timer();     
                  } 
                  else { // иначе
                     if (newValue > temp_off) { //Если температура датчика больше xx градусов
                       	Stop_Timer();
                         dev["wb-gpio"]["EXT3_R3A1"] = false; //Здесть указать имя своего модуля, установи  модуля wb-gpio в состояние "выключено"
                     	dev["wb-gpio"]["EXT3_R3A2"] = false; //Здесть указать имя своего модуля, установи  модуля wb-gpio в состояние "выключено"
                         log.info("Stop skvaz timer and off relay, temp > {}",temp_off);
                     }
                  }
            } 
           else {  // если вируальн. устр-во Upravl obogrev skvazina в положении disable, выключаем реле и завершаем таймеры
               Stop_Timer(); 
               dev["wb-gpio"]["EXT3_R3A1"] = false; //установи R3A1 модуля wb-gpio в состояние "выключено"
               dev["wb-gpio"]["EXT3_R3A2"] = false; //установи R3A2 модуля wb-gpio в состояние "выключено"
               log.info("Stop skvaz timer and off relay, button 'Upravl obogrev skvazin-drenaz' disable");
             
           }
          
         }
 
 });

Не много не понятна ТЗ, как Вы здесь указали, нужна цикличности вкл и выкл обогрева, но по коду вижу, что есть еще ограничения по температуре и контроль запуска правила по кнопки.
Могли бы Вы указать более точно, что нужно. Т.к. в данном варианте правило привязано к изменениям термометра и мне кажется так делать совсем верно в данном случаи.

Попробуйте вот этот…

var relay_on_timer_id = null;
var relay_off_timer_id = null;
var temp_on = -3;  // Указать свою температуру
var temp_off = -1; // Указать свою температуру

defineVirtualDevice ("control_heating", {
 	title: "Well heating",
 		cells: {
   		  enabled: {
    	    type: "switch",
    	    value: false,
          },
  }
});

function on_timer() {    
  //log.info("in function on_timer()");
  dev["wb-gpio"]["EXT2_R3A1"] = true; //Здесть указать имя своего модуля,установи модуля wb-gpio в состояние "включено"
  dev["wb-gpio"]["EXT2_R3A2"] = true; //Здесть указать имя своего модуля установи модуля wb-gpio в состояние "включено"
  relay_on_timer_id = setTimeout(function() {
     off_timer();
  }, 10000); //для теста 10 сек во включенном положении, 2 часа это будет 26060*1000       
  log.info("Relay ON, Wait 10s");
 }
     
function off_timer() {
 // log.info("in function off_timer()");
  dev["wb-gpio"]["EXT2_R3A1"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
  dev["wb-gpio"]["EXT2_R3A2"] = false; //Здесть указать имя своего модуля, установи модуля wb-gpio в состояние "выключено"
  relay_off_timer_id = setTimeout(function() {
     on_timer();
  }, 30000); //для теста 30 сек в выключенном положении, 2 часа это будет 2*60*60*1000
 log.info("Relay OFF, Wait 30s");
}

function Stop_Timer(){
  log.info("Timer stop");
  if (relay_on_timer_id)  {relay_on_timer_id = clearTimeout(relay_on_timer_id);};  
  if (relay_off_timer_id) {relay_off_timer_id = clearTimeout(relay_off_timer_id); };
  dev["wb-gpio"]["EXT2_R3A1"] = false; //установи R3A1 модуля wb-gpio в состояние "выключено"
  dev["wb-gpio"]["EXT2_R3A2"] = false; //установи R3A2 модуля wb-gpio в состояние "выключено"  
}

defineRule("timer_button",{
  whenChanged: "control_heating/enabled",
    then: function(){
        if (dev.control_heating.enabled){
              if ( !(relay_on_timer_id||relay_off_timer_id) ){
                on_timer();
              }
        }
        else{
          Stop_Timer();
        }  
 	}
});


defineRule("rules control heating", { //название правила - “контроль обогрева скважины”
        whenChanged: "wb-w1/28-00000b0ff412", //при изменении состояния датчика wb-w1/28-00000b0ff412
        then: function(newValue, devName, cellName) { //выполняй следующие действия 
          log.info("rules control heating then:");
            if (dev.control_heating.enabled) { // если вируальн. устр-во в положении enabled
                log.info("newValue ={}",newValue);
                if (newValue < temp_on) { //если температура датчика меньше xx градусов
                    if (!(relay_on_timer_id||relay_off_timer_id)){on_timer();} 
                  	log.info("Stop timer and off relay, temp > {}",temp_on);
                 } 
                 else { // иначе
                    if (newValue > temp_off) { //Если температура датчика больше xx градусов
                      	Stop_Timer();                       
                        log.info("Stop timer and off relay, temp > {}",temp_off);
                    }
                 }
           } 
          else {  // если вируальн. устр-во Upravl obogrev skvazina в положении disable, выключаем рыле и завершаем таймеры
              Stop_Timer();               
              log.info("Stop timer and off relay, button 'Well heating' disable");            
          }
         
        }

});

Да, давайте уточню: действительно нужно запускать нагрев по таймеру, 2 часа работаем, 4 отдыхаем. Чтобы в принципе можно было управлять работой скрипта- нужен переключатель вкл-выкл. И, в идеале, пытался сделать так, чтобы подогрев работал только при минусовых температурах. Те условия запуска таймера - переключатель в положении вкл и температура меньше, например, -2

Я примерно это и понял, у меня последний вариант работает без ошибок.
Т.е. кнопкой контролируем активность правила, а по изменениям данный с датчика контролируем выход за рамки по температуре. Вы его проверяли?

не успел еще, обязательно проверю, отпишусь

Отрабатывает все четко, спасибо огромное!!

а вот тут

if (dev.control_heating.enabled) { // если вируальн. устр-во в положении enabled
log.info(“newValue ={}”,newValue);
if (newValue < temp_on) { //если температура датчика меньше xx градусов
if (!(relay_on_timer_id||relay_off_timer_id)){on_timer();}
log.info(“Stop timer and off relay, temp > {}”,temp_on);

в лог не Start timer and on relay, temp < {}",temp_on ?

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

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

(function () {
'use strict';

var ActionButtons = {};


/**
 * Version: 0.3.1
 * 
 * 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 "triplePress" 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"]},
 *                                      triplePress: {func: myFunc3, prop: []},
 *                                      longPress: {func: myFunc4, prop: []},
 *                                      longRelease: {func: myFunc5, 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).
 * @param  {number} intervalOfRepeat - Time (ms) before repeating action specified in LongPress action. Default is 50 ms.
 * 
 * Note: In case longRelease function defined, longPress function will repeate till button is released.
 *       In case longRelease function not defined, only one action will be executed for longPress.
 */
ActionButtons.onButtonPress = function (trigger, action, timeToNextPress, timeOfLongPress, intervalOfRepeat) {
    
    // Set default values if not passed into function
timeToNextPress = timeToNextPress || 300;
timeOfLongPress = timeOfLongPress || 1000;
intervalOfRepeat = intervalOfRepeat || 100;

var buttonPressedCounter = 0;
var actionRepeatCounter = 0;
var timerWaitNextShortPress = null;
var timerLongPress = null;
var timerWaitLongRelease = null;
var isLongPressed = false;
var isLongReleased = false;

var ruleName = "on_button_press_" + trigger.replace("/", "_").replace(/ /g, "_"); //Добавил условие для удаления пробелов
log("LOG::Define WB Rule: ", ruleName);

defineRule(ruleName, {
    whenChanged: trigger,
    then: function (newValue, devName, cellName) {
        //  Вставка для работы со счетчиками нажатий 	
        var isButtonPressed = newValue;
        if (typeof newValue === "number"){
        	isButtonPressed = newValue % 2 !== 0;
        }

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

            if (timerWaitNextShortPress) {
                clearTimeout(timerWaitNextShortPress);
            }
            timerLongPress = setTimeout(function () {
                isLongPressed = true;  // Long press identified, we will skip short press
                isLongReleased = false;
                buttonPressedCounter = 0;
                actionRepeatCounter = 1;
                if (typeof action.longPress === "object") {
                    if (typeof action.longPress.func === "function") {
                        action.longPress.func.apply(this, action.longPress.prop);
                        // If Long Release action define, we will repeat Long Press action till not released. Otherwise only 1 Long Press action is executed
                        if (typeof action.longRelease === "object") {
                            if (typeof action.longRelease.func === "function") {
                                timerWaitLongRelease = setInterval(function () {
                                    if(!isLongReleased) {
                                        if (typeof action.longPress === "object") {
                                            if (typeof action.longPress.func === "function") {
                                                action.longPress.func.apply(this, action.longPress.prop);
                                            }
                                        }
                                        // log(">>>>>> long press - press (" + actionRepeatCounter++ + ") <<<<<<");    
                                    }
                                    if(isLongReleased) {
                                        clearInterval(timerWaitLongRelease);
                                    }
                                }, intervalOfRepeat);        
                            }                                        
                        }

                    }
                }
                // log(">>>>>> long press - press (" + actionRepeatCounter++ + ") <<<<<<");
            }, timeOfLongPress);

        }

        // If button is released, then it is not a "long press", start to count clicks
        else {
            if (!isLongPressed) {
                if (timerLongPress) {
                    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;
                    // Counter equals 3 - it's a triple short press
                    case 3:
                        if (typeof action.triplePress === "object") {
                            if (typeof action.triplePress.func === "function") {
                                action.triplePress.func.apply(this, action.triplePress.prop);
                            }
                        }
                        // log(">>>>>> short press - triple <<<<<<");
                        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, []);
                        // }
                    }
                }
                // log(">>>>>> long press - release <<<<<<");
                isLongPressed = false;
                isLongReleased = true;
            }
        }

    }
});
};



// 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;
}

}());

const flatIOs = [
    { name: 'DI0', io: ['Counter 1', 'Counter 2', 'Counter 3', 'Counter 4', 'Counter 5', 'Counter 6', 'Counter 7', 'Counter 8', 'Counter 9', 'Counter 10', 'Counter 11', 'Counter 12', 'Counter 13', 'Counter 14'] },
    { name: 'R1', io: ['K1', 'K2', 'K3', 'K4', 'K5', 'K6'] },
    { name: 'R2', io: ['K1', 'K2', 'K3', 'K4', 'K5', 'K6'] }
];


ActionButtons.onButtonPress(
flatIOs[0].name +"/"+ flatIOs[0].io[0],          //Вход, за которым следим.
{
singlePress: {
   func: switchRelay,
   prop: [flatIOs[1].name, flatIOs[1].io[0]]
},
doublePress: {
   func: switchRelay, prop: [flatIOs[1].name, flatIOs[1].io[1]]
    //func: switchDimmerRGB,
    //prop: ["wb-mr6c_10", "K2", "wb-mrgbw-d_24"]
},
longPress: {
   func: switchRelay, prop: [flatIOs[1].name, flatIOs[1].io[2]]
    //func: setRandomRGB,
    //prop: ["wb-mr6c_10", "K2", "wb-mrgbw-d_24"]
}
},
300, 1000
);


/**
* Helper Functions
*/
function switchRelay(device, control) { //Принимает в параметрах устройство и выход. Переключает состояние выхода на противоположное.
  log.info("LongPress switchRelay", device, control)//Это лог. Он попадает в /var/log/messages
  dev[device][control] = !dev[device + "/" + control];
}

function switchDimmerRGB(relayDevice, relayControl, dimmerDevice) {
   dev[relayDevice][relayControl] = true;
   if (dev[dimmerDevice + "/RGB"] !== "0;0;0") {
     dev[dimmerDevice]["RGB"] = "0;0;0";
   }
   else {
     dev[dimmerDevice]["RGB"] = dev[relayDevice + "/RGB"];
   }
}

function setRandomRGB(relayDevice, relayControl, dimmerDevice) {
  dev[relayDevice][relayControl] = true;
  dev[relayDevice + "/RGB"] = "" + Math.floor(Math.random() * 255) + ";" + Math.floor(Math.random() * 255) + ";" + Math.floor(Math.random() * 255);
  dev[dimmerDevice]["RGB"] = dev[relayDevice + "/RGB"];
}

Добрый день!

Использовал ваш кусок кода для обработки 1-, 2-, Долгого- нажатий, все работает, но есть одна проблема, после запуска контроллера, автоматически включаются все выходы, где был использован этот код. Получается после подачи питания на щиток и загрузки контроллера, включается свет на тех реле где используется этот кусок кода (Version: 0.3.1), модули WB-MRPS6/S и WB-MDM3.

В лог выводится сообщение: LOG::Define WB Rule: on_button_press_wb-gpio_EXT5_IN10

Если закомментировать этот кусок кода: singlePress: { func: Switcher, prop: [“rele3”, “K5”] }, то после запуска контроллера свет автоматически не включается.

Значение регистра 6: 0: не восстанавливать состояние реле.

Код функции Switcher:
function Switcher(pDevace, pChanel){
dev[pDevace][pChanel] = !dev[pDevace][pChanel];
}

В чем проблема? Правила, свойствах, версии, настройки модуля?

Тут, думаю, дело в том что при апуске первым в mqtt топик приходит “null”, вызывая срабатывание. Можно либо сделать костыль, принудительно выключая все каналы реле либо исключить в скрипте обработку “null”.

Здравствуйте! Набросал код управления рулонными шторами.

defineRule(“roller cabinet down”, {
when: function(newValue, devName, cellName) {
return dev[“wb-gpio”][“EXT5_IN4”] = true;
},
then: function (newValue, devName, cellName) {
dev[“wb-gpio”][“EXT3_ON2”] = true;
dev[“wb-gpio”][“EXT3_DIR2”] = false;
}
});

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

defineRule(“roller cabinet down”, {
when: function(newValue, devName, cellName) {
return dev[“wb-gpio”][“EXT5_IN4”] = true;
},
then: function (newValue, devName, cellName) {
dev[“wb-gpio”][“EXT3_ON2”] = true;
dev[“wb-gpio”][“EXT3_DIR2”] = false;
setTimeout(function () {}, 30000);
dev[“wb-gpio”][“EXT3_ON2”] = false;
}
});

Подскажете, в чем может быть проблема?

И еще хотелось бы сделать так, чтобы при одном нажатии на кнопку штора опускалась до конца, а при повторном она останавливалась.

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

Заранее спасибо за помощь!

Здравствуйте!

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

defineVirtualDevice("drapery_control", {
    title: "Drapery Control",
    cells: {
        open: {
            type: "switch",
            value: false,
            order: 1,
        },
        close: {
            type: "switch",
            value: false,
            order: 2,
        },
    },
});

Результатом будет такое окно на странице Devices:
image

Сделал несколько исправлений, должно заработать:

defineRule("roller cabinet down", {
    whenChanged: ["drapery_control/close", "wb-gpio/EXT5_IN4"],  //правило срабатывает при активировании входа или включении кнопки в веб-интерфейсе
    then: function (newValue, devName, cellName) {
        if (newValue) {
            dev["wb-gpio"]["EXT3_ON2"] = true;
            dev["wb-gpio"]["EXT3_DIR2"] = false;

            setTimeout(function () {
                dev["wb-gpio"]["EXT3_ON2"] = false;   //прописываем действия по истечению времени
                dev["drapery_control"]["close"] = false;
            }, 3000);
        }
    },
});
2 лайка

Спасибо за ответ! Буду пробовать!

Подскажите, как еще сделать так, чтобы при повторном нажатии на кнопку (хотя бы реальную) штора останавливалась в текущем положении? То есть нужно переключить “wb-gpio”][“EXT3_ON2”] в false

Доработал правило отображения ресурсов контроллера: отображается загрузка процессора, сведения об оперативной памяти, сведения о разделе rootfs и сведения об /mnt/data. В правиле используются фрагменты кода из тем на портале техподдержки, которыми поделились пользователи. Возможно, кому-нибудь будет полезным.

image.

Правило во вложении.
controller_utilization.zip (1.0 KB)

Здравствуйте! Виртуальные кнопки создаются, но скрипт на них не реагирует…

defineVirtualDevice(“Roller blinds”, {
title: “Шторы”,
cells: {
Спальня_О: {
type: “switch”,
value: false,
order: 1,
},
Спальня_З: {
type: “switch”,
value: false,
order: 2,
},
},
})
;

defineRule(“roller sleeping room down”, {
whenChanged: [“Шторы/Спальня_З”, “wb-gpio/EXT5_IN8”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = true;
dev[“wb-gpio”][“EXT4_DIR3”] = false;

        setTimeout(function () {
            dev["wb-gpio"]["EXT4_ON3"] = false;  
            dev["Шторы"]["Спальня_З"] = false;
        }, 30000);
    }
},

});

defineRule(“roller sleeping room up”, {
whenChanged: [“Шторы/Спальня_О”, “wb-gpio/EXT5_IN9”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = true;
dev[“wb-gpio”][“EXT4_DIR3”] = true;

        setTimeout(function () {
            dev["wb-gpio"]["EXT4_ON3"] = false;  
            dev["Шторы"]["Спальня_О"] = false;
        }, 30000);
    }
},

});

Кнопки сейчас в отдельном правиле, помещал и в одно со скриптами - все равно ничего. Пробовал писать отдельное правило на виртуальные кнопки, тоже нет изменений

В условии нужно использовать имя виртуального устройcтва, а не его заголовок окна. Попробуйте так:

whenChanged: ["Roller blinds/Спальня_З", "wb-gpio/EXT5_IN8"],
1 лайк

Скрипт у меня такой:

defineRule(“roller sleeping room down”, {
whenChanged: [“Roller blinds/Спальня_З”, “wb-gpio/EXT5_IN8”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = true;
dev[“wb-gpio”][“EXT4_DIR3”] = false;

setTimeout(function () {
dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“Roller blinds”][“Спальня_З”] = false;
}, 30000);
}
},
});

Получается нужно сделать так?

defineRule(“roller sleeping room down”, {
whenChanged: [“Roller blinds/Спальня_З”, “wb-gpio/EXT5_IN8”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“wb-gpio”][“EXT4_DIR3”] = false;
dev[“wb-gpio”][“EXT4_ON3”] = true;

setTimeout(function () {
dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“Roller blinds”][“Спальня_З”] = false;
}, 30000);
}
},
});

пт, 14 янв. 2022 г. в 08:40, Explorerol через Wiren Board Support <info@wirenboard.ru>:

Не совсем так. Если вы отключаете реле и сразу его снова включаете, то контакты реле ON3 не успеют до конца разомкнуться, как придет команда снова на включение. Для отключения реле обычно 10-50 миллисекунд. Поэтому лучше отключить реле ON3, затем сделать паузу для ожидания отключения реле, например 100 мс, затем уже переключить реле DIR3, опять сделать паузу, а затем снова включить ON3.
То есть было так:

dev[“wb-gpio”][“EXT4_ON3”] = false;
dev[“wb-gpio”][“EXT4_DIR3”] = false;
dev[“wb-gpio”][“EXT4_ON3”] = true;

А станет, например, так:

var delay_ms = 100        

dev["wb-gpio"]["EXT4_ON3"] = false;

setTimeout(function () {
dev["wb-gpio"]["EXT4_DIR3"] = false;	
}, delay_ms);

setTimeout(function () {
dev["wb-gpio"]["EXT4_ON3"] = true;	
}, delay_ms * 2);

1 лайк

Подскажите еще: хочу сделать, чтобы при нажатии на кнопку один раз, штора доезжала до конца, при нажатии, второй раз - останавливалась. Идея такая: ввести переменную n, которая будет считать количество нажатий, то есть нажал один раз n=1, нажал второй раз n=2 и обнулилась после этого. При n=1 будет одна функция, при n=2 будет другая. Но как задать n? Если я задаю n после define rule, то выдает ошибку, если после whenchanged - тоже, если после then function, то норм, но тогда n всегда будет обнуляться при наступлении события нажатия на кнопку. У меня сейчас вот такой код:

defineRule(“roller cabinet room down”, {
whenChanged: [“Roller blinds/Кабинет_З”, “wb-gpio/EXT5_IN4”],
then: function (newValue, devName, cellName) {
if (newValue) {
dev[“Roller blinds”][“Кабинет_О”] = false;
dev[“wb-gpio”][“EXT3_ON2”] = false;
setTimeout(function () {
dev[“wb-gpio”][“EXT3_DIR2”] = false;
}, 100);
setTimeout(function () {
dev[“wb-gpio”][“EXT3_ON2”] = true;
}, 100);
setTimeout(function () {
if (“wb-gpio/EXT3_DIR2”==true) {
dev[“wb-gpio”][“EXT3_ON2”] = false;
dev[“Roller blinds”][“Кабинет_З”] = false; }
}, 30000);
}
},
});

пт, 14 янв. 2022 г. в 15:56, Explorerol через Wiren Board Support <info@wirenboard.ru>: