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

Ну как я понимаю для предложенной функции вы пишите очевидные вещи. Я и использую ее как функцию. Только вот результат возвращает она сомнительный для модуля который подгружен через require - по сути пустую строку.

log(objEXAM(SunCalc1));

2020-11-26 10:08:48 objEXAM enter
2020-11-26 10:08:48

Андрей, что тут не так? скрипт кривой и старый или я что то не так делаю?

Создайте пожалуйста отдельную тему, выложите свой скрипт - воспроизведу и посмотрю.

Сколько не пытался использовать PersistentStorage после перезагрузки он пустой…

var stor = new PersistentStorage("state-storage", {global: true});
log("Загруженное состояние [{}]",stor["light"]?"Включено":"Отключено");
if(stor["light"] == undefined){
    log("Не заданно начальное состояние");
    stor["light"] = dev["wb-mr6c_30/K1"];
}else{
   dev["wb-mr6c_30/K1"] = stor["light"];
}

Вобщем нужно как-то сделать чтобы реле не отключалось после перезапуска.

Проверяю.

var stor = new PersistentStorage("state-storage", {global: true});
log("Загруженное состояние [{}]",stor["light"]?"Включено":"Отключено");
stor["light"] = true;
log("Загруженное состояние 2 [{}]",stor["light"]?"Включено":"Отключено");

После выполнения:

2020-12-03 20:28:38Загруженное состояние [Отключено]
2020-12-03 20:28:38Загруженное состояние 2 [Включено]

Комментирую строку “stor[“light”] = true;”
и перезапускаю контроллер:

cat /var/log/messages |grep wb-rules
(skip)
Dec  3 17:33:12 wirenboard-ACAX3M6K daemon.info wb-rules[1959]: INFO: [rule info] Загруженное состояние [Включено]
Dec  3 17:33:12 wirenboard-ACAX3M6K daemon.info wb-rules[1959]: INFO: [rule info] Загруженное состояние 2 [Включено]

А вот сравнивать с переменной “undefined” - некорректно.

Посмотрите на использование например:

Добрый день! Подскажите, как сделать, нашел много примеров, но в них создают правила, привязанные к определенному времени, немного не то(
Задача: замыкать реле по таймеру, те: включаем, работает 2 часа, выключается, ждет 3 часа, цикл заного. и так бесконечно.
в идеале с разными интервалами от дня недели, но это как сделать знаю

Очень по-быстрому накидал код. Работает как вам надо.

function on() {

    console.log(1, Date());

    setTimeout(() => {

        off();

    }, 5000); //для теста 5 сек во включенном положении, 2 часа это будет 2*60*60*1000

}

function off() {

    console.log(0, Date());

    setTimeout(() => {

        on();

    }, 1000); //для теста 1 сек в выключенном положении, 2 часа это будет 2*60*60*1000

}

on();

Доработаете под свою логику с реле, сейчас пока вывод в консоль, тестировал в браузере.

1 лайк

Спасибо, пробую делать:

// Включение / выключение правила выключателем на панели Devices
// Создаём виртуальное устройство - выключатель.
defineVirtualDevice(“upravl_obogrev_skvazin”, {
title: “Upravl obogrev skvazina”,
cells: {
enabled: {
type: “switch”,
value: false
},
}
});

defineRule(“heater_skvazin_control”, { //название правила - “контроль обогрева скважины”
whenChanged: “wb-w1/28-00000b0ff412”, //при изменении состояния датчика wb-w1/28-00000b0ff412
then: function(newValue, devName, cellName) { //выполняй следующие действия
if (dev.upravl_obogrev_skvazin.enabled) { // если вируальн. устр-во Upravl obogrev skvazina в положении enabled
if (newValue < -5) { //если температура датчика меньше xx градусов
function on() {
dev[“wb-gpio”][“EXT3_R3A1”] = 1; //установи R3A1 модуля wb-gpio в состояние “включено”
dev[“wb-gpio”][“EXT3_R3A2”] = 1; //установи R3A2 модуля wb-gpio в состояние “включено”
setTimeout(() => {
off();
}, 5000); //для теста 5 сек во включенном положении, 2 часа это будет 260601000
}
function off() {
dev[“wb-gpio”][“EXT3_R3A1”] = 0; //установи R3A1 модуля wb-gpio в состояние “выключено”
dev[“wb-gpio”][“EXT3_R3A2”] = 0; //установи R3A2 модуля wb-gpio в состояние “выключено”
setTimeout(() => {
on();
}, 10000); //для теста 10 сек в выключенном положении, 2 часа это будет 2
60601000
}
on();
} else { // иначе
if (newValue > -3) { //если температура датчика больше xx градусов
dev[“wb-gpio”][“EXT3_R3A1”] = 0; //установи R3A1 модуля wb-gpio в состояние “выключено”
dev[“wb-gpio”][“EXT3_R3A2”] = 0; //установи R3A2 модуля wb-gpio в состояние “выключено”
}
}
}
}
});

ругается на 21 строку, подсветил жирным, не пойму, что не так сделал

Функция вызова таймера пишется так

setTimeout(function (){
 off();
}, 5000);

setTimeout(function()  {
   on();
}, 10000);



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

// Включение / выключение правила выключателем на панели Devices
// Создаём виртуальное устройство - выключатель.
defineVirtualDevice(“upravl_obogrev_skvazin”, {
title: “Upravl obogrev skvazina”,
cells: {
enabled: {
type: “switch”,
value: false
},
}
});

defineRule(“heater_skvazin_control”, { //название правила - “контроль обогрева скважины”
whenChanged: “wb-w1/28-00000b0ff412”, //при изменении состояния датчика wb-w1/28-00000b0ff412
then: function(newValue, devName, cellName) { //выполняй следующие действия
if (dev.upravl_obogrev_skvazin.enabled) { // если вируальн. устр-во Upravl obogrev skvazina в положении enabled
if (newValue < -5) { //если температура датчика меньше xx градусов
function on() {
dev[“wb-gpio”][“EXT3_R3A1”] = 1; //установи R3A1 модуля wb-gpio в состояние “включено”
dev[“wb-gpio”][“EXT3_R3A2”] = 1; //установи R3A2 модуля wb-gpio в состояние “включено”
setTimeout(function() {
off();
}, 5000); //для теста 5 сек во включенном положении, 2 часа это будет 26060*1000
}

            function off() {
                dev["wb-gpio"]["EXT3_R3A1"] = 0; //установи R3A1 модуля wb-gpio в состояние "выключено"
                dev["wb-gpio"]["EXT3_R3A2"] = 0; //установи R3A2 модуля wb-gpio в состояние "выключено"
                setTimeout(function() {
                    on();
                }, 10000); //для теста 10 сек в выключенном положении, 2 часа это будет 2*60*60*1000
            }
            on();
        } else { // иначе
            if (newValue > -3) { //если температура датчика больше xx градусов
                dev["wb-gpio"]["EXT3_R3A1"] = 0; //установи R3A1 модуля wb-gpio в состояние "выключено"
                dev["wb-gpio"]["EXT3_R3A2"] = 0; //установи R3A2 модуля wb-gpio в состояние "выключено"
            }
        }
    }
}

});

Попробуйте это правило и не забудьте указать название своих устройств.

var Thermometer = "wb-2000/temperatura"; // Здесь указать свой датчик
var relay_on_timer_id = null;
var relay_off_timer_id = null;
var temp_on = 3;  // Указать свою температуру
var temp_off = 5; // Указать свою температуру

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

});

Отлично, все работает, спасибо, может еще кому-нибудь пригодиться тоже)

Выяснился нюанс(( Скрипт отрабатывает включение, тестовые 10 сек работает timer_on, отключается, но не на 40 сек, а на 3, тут же включается, далее 10 сек работы, потом сообщения начинают задваиваться, но работает примерно так же. А вот если выключить правило, то скрипт работает по правильным таймингам, но остановиться спустя 10 минут только

2021-02-27 22:00:20Relay skvaz OFF, Wait 4ch

2021-02-27 22:00:22Relay skvaz ON, Wait 2ch

2021-02-27 22:00:32Relay skvaz OFF, Wait 4ch

2021-02-27 22:00:33Relay skvaz ON, Wait 2ch

2021-02-27 22:00:34Relay skvaz ON, Wait 2ch

2021-02-27 22:00:43Relay skvaz OFF, Wait 4ch

2021-02-27 22:00:44Relay skvaz OFF, Wait 4ch

2021-02-27 22:00:59Relay skvaz ON, Wait 2ch

2021-02-27 22:01:00Relay skvaz ON, Wait 2ch

2021-02-27 22:01:09Relay skvaz OFF, Wait 4ch

2021-02-27 22:01:10Relay skvaz OFF, Wait 4ch

2021-02-27 22:01:12Relay skvaz ON, Wait 2ch

2021-02-27 22:01:22Relay skvaz OFF, Wait 4ch

2021-02-27 22:01:23Relay skvaz ON, Wait 2ch

2021-02-27 22:01:24Relay skvaz ON, Wait 2ch

2021-02-27 22:01:28Stop skvaz timer and off relay, button ‘Upravl obogrev skvazin-drenaz’ disable

2021-02-27 22:01:33Relay skvaz OFF, Wait 4ch

2021-02-27 22:01:40Stop skvaz timer and off relay, button ‘Upravl obogrev skvazin-drenaz’ disable

2021-02-27 22:01:49Relay skvaz ON, Wait 2ch

2021-02-27 22:01:50Relay skvaz ON, Wait 2ch

2021-02-27 22:01:59Relay skvaz OFF, Wait 4ch

2021-02-27 22:02:00Relay skvaz OFF, Wait 4ch

2021-02-27 22:02:39Relay skvaz ON, Wait 2ch

2021-02-27 22:02:40Relay skvaz ON, Wait 2ch

2021-02-27 22:02:49Relay skvaz OFF, Wait 4ch

2021-02-27 22:02:50Relay skvaz OFF, Wait 4ch

2021-02-27 22:03:29Relay skvaz ON, Wait 2ch

2021-02-27 22:03:30Relay skvaz ON, Wait 2ch

2021-02-27 22:03:39Relay skvaz OFF, Wait 4ch

2021-02-27 22:03:40Relay skvaz OFF, Wait 4ch

2021-02-27 22:04:19Relay skvaz ON, Wait 2ch

2021-02-27 22:04:20Relay skvaz ON, Wait 2ch

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

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

 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

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

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

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