Выключение реле с задержкой после включение

Добрый день!
У меня есть устройство для подачи сигнала на который нужно кратковременно замкнуть 2 контакта.
Пытаюсь написать правило, которое при замыкании реле, через 2 секунды его размыкает.
Но что-то не получается. Никак не осилю setTimeout
Вот что у меня получается (вернее не получается):

    var doorLock_timer_id = null;

    defineRule("door_lock", { 
      whenChanged: "wb-gpio/EXT2_R3A1", 
      then: function (newValue, devName, cellName) { 
    doorLock_timer_id = setTimeout(function() {
        return dev["wb-gpio"]["EXT2_R3A1"] = newValue;
    }, 2000);
    clearTimeout(doorLock_timer_id); 
      dev["wb-gpio"]["EXT2_R3A1"] = !newValue;     
      }
    });

Добрый день!

Попробуйте две вещи:

  1. Вместо изменения контрола выполняйте отладочную печать через log() (чтобы увидеть вывод, нажмите на гаечный ключ справа внизу).
  2. Посмотреть примеры отсюда: https://wirenboard.com/wiki/index.php/Движок_правил_wb-rules

Я пробовал вставлять логирование. Получается, что в setTimeout (return dev[“wb-gpio”][“EXT2_R3A1”] = newValue;) я вообще не попадаю

это вообще странная конструкция. Зачем здесь return?

Добрый день!

В вашем примере таймер сбрасывается сразу после выставления и соответственно никогда не срабатывает. Таймер нужно пытаться сбросить (если он уже ранее был выставлен) перед выставлением.
Не тестировал, но так должно работать:

    var doorLock_timer_id = null;

    defineRule("door_lock", { 
      whenChanged: "wb-gpio/EXT2_R3A1", 
      then: function (newValue, devName, cellName) {
        doorLock_timer_id && clearTimeout(doorLock_timer_id); 

        doorLock_timer_id = setTimeout(function() {
          dev["wb-gpio"]["EXT2_R3A1"] = newValue;
        }, 2000);
        dev["wb-gpio"]["EXT2_R3A1"] = !newValue;     
      }
    });
1 лайк
Так пробовали?

    var timer_id = null;
    defineRule("door_lock", {
        	asSoonAs: function () {
            	return dev["wb-gpio/EXT2_R3A1"];
          	},
        	then: function (newValue, devName, cellName) 
        	{ 
              	timer_id = setTimeout(function() {
                    dev["wb-gpio/EXT2_R3A1"] = false;
                    clearTimeout(timer_id);
                }, 2000);
            }
        });

так почему-то реле несколько раз подряд щелкало в течении указанных 2сек…

Ваш вариант заработал!
Спасибо большое!
Только я так и не смог понять как работает конструкция asSooAs/then
Можете пояснить?

Как только результат функции, который под asSoonAs = true, выполняется функция после then. Как я понял - функция setTimeout - просто выполняет один раз функцию, которая передается ей в качестве аргумента, с указанной задержкой. Далее все, поэтому запоминать timer_id и делать clearTimeout не нужно, все сделает GC. Я у себя в похожем коде clearTimeout не делаю. Если не прав, поправте меня, кто знает.

а почему тогда вместо asSoonAs нельзя использовать when?

Подскажите, пожалуйста, что я делаю не так.
Я создал виртуальное устройство и по изменению одного из переключателей хочу сделать управление модулем управления роллет ( WBIO-DO-R10R-4) - т.е. опускаться сколько-то секунд, потом остановиться.

Цитата
defineVirtualDevice(“ht”, {
title: “Управление домашним кинотеатром”,
cells: {
projScreen_up: {
type: “switch”,
value: false
},
projScreen_down: {
type: “switch”,
value: false
},
projScreen_higher: {
type: “switch”,
value: false
},
projScreen_lower: {
type: “switch”,
value: false
}
}
});

var relay_down_timer_id = null;

defineRule("r_projScreen_down", {
   asSoonAs: function () {
         return dev["ht/projScreen_down"];
   },
   then: function (newValue, devName, cellName) 
   { 
       relay_down_timer_id = setTimeout(function() {
            dev["wb-gpio/EXT3_ON1"] = true;
            dev["wb-gpio/EXT3_DIR1"] = true;
            clearTimeout(relay_down_timer_id);
  			log('Экран опускается...');   
       }, 2000);
       dev["wb-gpio"]["EXT3_ON1"] = false; log('Экран стоп...'); 
   }
});

но не работает…
Во-первых, при включении он сначала пишет в лог “Экран стоп” и только через 1-2 секунды включается и пишет в лог “Экран опускается”
Во-вторых, при выключении переключателя реле продолжает работать

Что я делаю не так?

Всё логично. Смотрим GitHub - wirenboard/wb-rules: Rule engine for Wiren Board

setTimeout(callback, milliseconds) запускает однократный таймер, вызывающий при срабатывании функцию, переданную в качестве аргумента callback . Возвращает положительный целочисленный идентификатор таймера, который может быть использован в качестве аргумента функции clearTimeout() .

То есть запустили таймер, который через две секунды выполнит функцию. Запустили таймер, перешли к следующей инструкции, потом к log('Экран стоп...'); Таймер всё это время тикает, когда дотикает - выполнит log('Экран опускается...');

Спасибо! Исправил и заработало, хотя и не до конца осознаю эту конструкцию…