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

Помогите, пожалуйста, сделать правило для мигалки! Я написал, чтобы через 10 секунд включалась лампочка и мне нужно, чтобы она отключилась на 3 секунды, а затем снова включилась на 5 секунд. и так 15 раз. после чего обнулить таймер и
выключить лампочку.

var motion_timer_5_timeout_ms = 10 * 1000;
var motion_timer_5_id = null;
 
defineRule("svet_miganie_1", 
{
when: function ()
{
return dev["wb-gpio/EXT6_DR1"] ==1; 
},
then: function() 
{
if (motion_timer_5_id)
{
clearTimeout(motion_timer_5_id);
}
motion_timer_5_id = setTimeout(function () 
{
    dev["wb-gpio"]["EXT1_R3A2"] = 1;
motion_timer_5_id = null;   
},
motion_timer_5_timeout_ms);
}
});

Прочитайте пожалйуста первое сообщение темы и пропустите код через http://jsbeautifier.org/ , прежде чем постить, если он у вас отформатирован по левому краю.

Подскажите пожалуйста,
есть ли какой-то способ ловить двойные или тройные нажатия на нефиксирующуюся кнопку?
И зафиксировать “долгое” нажатие?

Спасибо

А кнопка куда подключена?

Пока на сухой контакт wb5, но это временное решение - кнопок планируется штук 20 и я пока не понимаю куда их все подключить

Можно расширять, через WBIO-DI-DR-16 например.

Про двойные и долгие нажатия: можно поэкспериментировать с правилами. Сделайте правило с whenChanged на канал кнопки, добавьте отладочный вывод на срабатывание (log). Он должен выводиться на каждое нажатие кнопки, хоть и с небольшой (<~100ms) задержкой. Дальше можете в правиле завести глобальную переменную-счётчик и сбрасывать её значение по таймеру.
Как-то так (код не проверял):

    (function() { //don't touch this line
      var button_counter = 0;
      var counter_clear_timer_id = null;

      defineRule( "on_button_press", {
        whenChanged: "wb-gpio/A1_IN",
        then: function (newValue, devName, cellName) {

          // если поймали нажатие, увеличиваем счётчик
          if (newValue) {
            button_counter += 1;
          }
          
          // счётчик равен двум, значит было двойное нажатие
          if (button_counter == 2) {
            log("double press!");
          }
 
          // после каждого нажатия сбрасываем таймер (удяляем старый)
          if (counter_clear_timer_id) {
            clearTimeout(counter_clear_timer_id);
          }
         
          // и взводим новый таймер, который сбросит счётчик через 2 секунды
          counter_clear_timer_id = setTimeout(function() {
            button_counter = 0;
          }, 2000);
        }
      });
    })();
1 лайк

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

как только у меня всё причешется, я обязательно всё выложу. Но уже готов посмотреть на ваши творения =)

сразу скажу, что очень многое взял из примеров других участников, выкладываю несколько правил. повторные правила включать в архив не стал, так как там изменены только номера таймеров и входов. в реализации ещё ооочень много всего поэтому по мере обновления правил архив будет пополняться. Прошу и других участников выкладывать правила, которые работают. так мы быстрее начнём создавать более сложные и интересные сценарии. а вот и ссылка https://yadi.sk/d/KKIDK4msyZNxn

Друзья, а никто не использовал конструкцию asSoonAs ?
Пытаюсь написать триггер на превышение температурного порога в 90градусов.
Но видимо где-то что-то недопонимаю:

defineRule(“SendSMS”, {
asSoonAs: function () { return dev[“wb-w1/28-28-031661768dff”] > 90;
},
then: function() {
Notify.sendSMS( номер тф, ‘text’’ );
}
});

А что именно не работает? Какая ошибка?

конструкцияя dev[“device/control”] поддерживается с версии 1.5.2, если мне не изменяет память, так что попробуйте на всякий случай обновить wb-rules:

apt-get update && apt-get install wb-rules
1 лайк

Конструкция рабочая, однако я ошибся в синтаксисе, пороговое значение должно быть указано в кавычках !

Натолкните на мысль, как описать условие ОТСУТСВИЯ получения данных с внешнего устройства. ( цель описать полное отключение электроэнергии на вводе в дом)

Сейчас толком не поддерживается. У нас есть тикет на поддержку статуса ошибки (meta/error) в движке правил, но это пока не реализовано.

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

Если приходят новые данные, то старый таймер отключается, взводится новый.
Пример можно посмотреть тут: http://contactless.ru/wiki/index.php/Движок_правил_wb-rules , правила motion_detector так и делают.

1 лайк

Внесу свою лепту.
Правило отрабатывает включение и выключение электрокотла подключенному к выходу A1 с 23:00 до 07:00 с ориентировкой на датчик температуры в комнате. Температура срабатывания - 22градуса, выключение - 25 градусов. С проверкой начального статуса ( вкл\выкл). Единственный минус - это невозможность вручную управлять котлом в процессе работы правила. Но это, я думаю, решаемо. Все контрольные точки пишутся в лог.


defineRule("BoilerON", {
  asSoonAs:
        function ()
{
    var date = new Date();
    var date_start = new Date(date);
    var S = dev["wb-gpio/A1_OUT"];
    var date_end = new Date(date);
    date_start.setHours(07);
    date_start.setMinutes(00);
    date_end.setHours(23);
    date_end.setMinutes(00);
    if ((date > date_start) && (date < date_end))
        {
        S=0;
        log(date +' Boiler disabled due to date time')
        }
    else
    {
    if ( dev["wb-w1/28-0316622907ff"] < "22" )
        {
        S=1;
        log(date + ' Boiler enabled, temp is lower then 22 C')
        }
    if (dev["wb-w1/28-0316622907ff"] > "25")
        {
        log(date +' Boiler disable, temp is higher then 25 C')
        S=0;
        }
    }
    return dev["wb-gpio/A1_OUT"] !=S;
},
then:
function ()
    {
    var date = new Date();
    var S=0;
    if (dev["wb-gpio/A1_OUT"] == 0)
        S=1;
    else
        S=0;
    dev["wb-gpio/A1_OUT"] =S;
    log(date + ' boiler status:' +S);
    }
});

1 лайк

у нас форматирование кода в движке к сожалению не автоматическое, так что:

Принято, исправлено ! Спасибо.

Всем привет! есть рабочая и готовая к использованию библиотека для вычисления восхода и захода солнца. взять можно отсюда:
https://yadi.sk/d/fq5-VDFB39nHAh
помогите написать правило основываясь на этой библиотеке! я что-то пытался делать, но к сожалению так ничего и не сработало. правило начинает срабатывать после восхода солнца.


var SunCalc = require('/data/uploads/suncalc-master'); //библиотека
лежит по пути /data/uploads 
var lat = 56.0;
var lng = 92.56;

defineRule("svet", 
{
when: function ()
{
return dev["wb-gpio/EXT6_DR1"] ==0; // при размыкании входа запускаем
правило. 
},
then: function() 
{
var date = new Date();
var times = SunCalc.getTimes(date, lat, lng);
var sunriseHours   = times.sunrise.getHours();
var sunriseMinutes = times.sunrise.getMinutes();
var sunsetHours   = times.sunset.getHours();
var sunsetMinutes = times.sunset.getMinutes();
var nowHours   = date.getHours();
var nowMinutes = date.getMinutes();
if((nowHours > sunriseHours) && (nowMinutes > sunriseMinutes))
{
    dev["wb-gpio"]["EXT1_R3A2"] = 1; //включаем реле 
}
}
});

помогите найти ошибку!

1 лайк

День добрвый!

Ошибка в сравнении времени:
if((nowHours > sunriseHours) && (nowMinutes > sunriseMinutes))

Если восход в 8:30 а сейчас 9:20 то условие (nowMinutes > sunriseMinutes) не выполнится: 20 < 30, следовательно, не выполнится и все условие if.
Время можно сравнивать проще. Почитайте тут: Описание сравнения времени

Извините, но я ничего особо не понял. в английском не силён, да и в java script тем более. я только начинаю чуть чуть понимать. помогите если можно? как должно это правило выглядеть в моём случае? спасибо!