Периодически срабатывающее правило

Помогите, пожалуйста! как написать правило, чтобы оно срабатывало каждые 10 секунд? пример: сработал датчик движения и нужно включить лампу, чтобы она мигала каждые 10 секунд, ну и после 10 минут такого мигания выключилась. напишите пример такого правила. пусть вход будет реле MRM2, а выход где висит лампа реле на модуле MR14. напишите, если не сложно. буду благодарен!

Ну неужели никто не поможет???

Поможет setTimeout

Боюсь, что не поможет. эта функция направлена на однократное срабатывание, а мне нужно, чтобы таймер срабатывал периодически.

ну что-то вроде:

var counter = 10; 
var period = 1000; // мс

function led_blink() {
   log("blink!");  // что-то делать

   counter -= 1; // сколько раз осталось вызывать
   
   if (counter > 0) { // если не последний раз, планируем ещё один вызов
      setTimeout(led_blink, period);
  }
}

led_blink(); // вызываем первый раз

1 Like

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

var counter20 = 20;
var period = 3*1000;
var timer_server_ms = 60 * 1000;
var timer_server = null;
var flag = 0;

function led_blink()
{
     if(flag == 0) 
{
         dev["wb-gpio"]["EXT1_R3A2"] = 1;
         flag = 1;
     }
     else 
{
         dev["wb-gpio"]["EXT1_R3A2"] = 0;
         flag = 0;
     }
     counter20 -= 1;

     if (counter20 > 0) 
{
         setTimeout(led_blink, period);
     }
}


defineRule("svet_v_servernoy_1",
{
     when: function ()
     {
         flag = 0;
         return dev["wb-gpio/EXT6_DR1"] ==1;
     },
     then: function ()
     {
         led_blink();
         if (timer_server)
         {
             clearTimeout(timer_server);
             dev["wb-gpio"]["EXT1_R3A2"] = 0;
             timer_server = null;
         },
         timer_server_ms);
     }
});

А вы его пробовали собирать? Там вот эта конструкция непонятна движку:

        timer_server_ms);```
Он ругается на нее. Вы ей что хотите сделать? Прокомментируйте, пожалуйста!

да, там должно быть не }, а } но от этого изменения всё-равно ничего не изменилось. правило не работает.

var counter = 10;
var period = 1000; // мс

function led_blink() {
log(“blink!”); // что-то делать

dev[“wb-gpio/EXT6_DR1”] =!dev[“wb-gpio/EXT6_DR1”]

counter -= 1; // сколько раз осталось вызывать

if (counter > 0) { // если не последний раз, планируем ещё один вызов
setTimeout(led_blink, period);
}
}

led_blink(); // вызываем первый раз

странная конструкция. что она обозначает?
вот моё правило:

var counter = 10; 
var period = 3*1000;
var timer_server_ms = 60 * 1000;
var timer_server = null;

function led_blink()
{
     dev["wb-gpio/EXT6_DR1"] =!dev["wb-gpio/EXT6_DR1"];
     counter -= 1;

   if (counter > 0)
{
         setTimeout(led_blink, period);
     }
}


defineRule("svet_v_servernoy_1",
{
     when: function ()
     {
         return dev["wb-gpio/EXT6_DR1"] ==1;
     },
     then: function ()
     {
         led_blink();
         if (timer_server)
         {
             clearTimeout(timer_server);
             dev["wb-gpio"]["EXT1_R3A2"] = 0;
             timer_server = null;
         }
         timer_server_ms);
     }
});

но оно тоже не работает. где ошибка?

Я не програмист, правильно не отвечу. Я лишь скопипастил эту “странную конструкцию”, но если логически подумать, то предположу, что при просмотре этой строки происходит сравнение значения двух переменных и если переменные равны(а они всегда равны, т.к переменная сравнивается сама с собой), то меняем значение на противоположное. Если добавить после этой строки log(dev[“wb-gpio/EXT6_DR1”]); то увидите в логах ни что иное, как 010101010101…
По чему не работает ваше не скажу, не знаю, но, поставив log(“метка”); в ключевых точках, думаю, осилите сами. имхо

Я голосую за простые и легко понимаемые программы! :slight_smile:
Задача простая по сути: в течение какого-то периода мигать лампой. Так давайте сделаем “мигатель” и “реле времени” для отмеривания этого периода мигания. Смотрите, что получилось у меня:

//Инициализация 
//частота мигания лампочки
var blinker_interval = 1* 500 //ms
//время, в течение которого будет мигать
var achtung_interval = 10* 1000 //ms


//Останавливаем таймеры, нужно при отладке, в продакшн-версии не требуется
//timers.blink_.stop(); 
//timers.achtung.stop();


// Для решения исходной задачи 
// создаем два таймера: один мигает (blink_), другой выжидает 20 минут (achtung).

// Мигаем лампочкой таймером типа startTicker(), так как он обеспечивает периодическое срабатывание
// А вот интервал, в течение которого лампочка будет мигать, задаем  таймером setTimeout()  -- он как раз обеспечивает однократность выполнения


// Правило для мигания -- на каждое срабатываение таймера изменить состояние реле

defineRule("Blinker", {
  when: function () { return timers.blink_.firing; },
  then: function () {dev["wb-mr11_79"]["K2"] =! dev["wb-mr11_79"]["K2"]; 
    log ("blink!");
   }
});

// Основное правило для запуска мигания -- в нашем примере ждем, пока реле ["wb-mr11_79"]["K3"] не сработает. Тут, конечно, можно любое условие использовать
// в качестве триггера

// В правиле мы запускаем таймер мигания blink_ и взводим таймер achtung

defineRule("Achtung", {
  asSoonAs: function () {
    return dev["wb-mr11_79"]["K3"] == true;
  },
  then: function () {
    startTicker("blink_", blinker_interval);
    startTimer("achtung", achtung_interval);
  }
});

// Таймер achtung сработал -- останавливаем мигание, выключаем лампочку.

defineRule("StopBlinker", {
  when: function () { return timers.achtung.firing; },
  then: function () {timers.blink_.stop(); dev["wb-mr11_79"]["K2"] = 0; 
    log ("stop blinking!");
   }
});

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

2 Likes

Выражаю огромную благодарность за внятное, полностью рабочее и ооочень нужное правило. спасибо большое!

ну а теперь если можно вопрос? как сделать так чтобы вместо реле воспроизводился бы звуковой файл. например нужно чтобы система каждые 30 секунд воспроизводила звуковое сообщение пусть это будет например runShellCommand(“mpg123 /mnt/data/sounds/123.mp3”); я верю, что вместе можно осилить такое не простое дело, как написание правил :slight_smile:

Рад помочь!

Я бы увеличил blinker_interval до 30 секунд и вместо щелканья релюхой dev["wb-mr11_79"]["K2"] =! dev["wb-mr11_79"]["K2"]; проигрывал бы звук через runShellCommand().

В правиле StopBlinker не нужно тогда отключение реле dev["wb-mr11_79"]["K2"] = 0;

123.mp3 лучше не делать длиной больше 30 секунд. Так сказать, во избежание.

спасибо ещё раз! тогда позвольте спросить ещё очень нужную конструкцию! как написать правило, чтобы оно срабатывало так:

замкнули вход. 
подождали 10 секунд 
включили реле 1. 
подождали 30 секунд 
выключили реле1. 
подождали 40 секунд. 
включили реле 2. 

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

Джаваскрипт асинхронный, функции типа sleep(), соответственно, нет. Делайте таймеры, переключайте виртуальные девайсы, меняйте состояние флагов. В таймерах нет ничего плохого.

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