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

Эта тема создана для обмена правилами или фрагментами кода, которые могут оказаться полезными другим пользователям и начинающим.

Основная статья в wiki про движок правил: http://contactless.ru/wiki/index.php/Движок_правил_wb-rules
Имеющиеся в wiki примеры повторять здесь не стоит.
Так же некоторые примеры можно найти на форуме, воспользовавшись поиском, например в этой теме
TODO: возможно, стоит перенести из той темы сюда или в wiki чтоб было единое место

Обязательно описание что правило делает и придерживание стандартного стиля написания кода на JavaScript. Также желательны комментарии в коде (не обязательно комментировать каждую строчку, только основные или нетривиальные моменты).
Для оформления блока кода, ставьте перед и после него на отдельной строке три символа косой кавычки (`, backtick)

5 лайков

Доброго времени суток, уважаемый ALL !
Может кто подскажет … Сделал правило для работы котла по расписанию в зависимости от температуры
в доме. Хочется прикрутить CRON чтобы учитывал рабочий день или выходной. Чего-то никак не получается.
Сам cron работает - правило с чисто включением по времени идёт. А вот чтобы время и температурный датчик
никак… :confused: Литературу, которая тут приводилась - читал., но соображалки не хватает…
Вот примерчик - включение реле по сопротивлению фоторезистора и по крону. Не должно вроде срабатывать., а работает …
Ткните носом - что не так…
Спасибо.

///
// Работа с CRON

defineRule("Rule_Cron",{
  when: cron("1 1 1 1 1 1"),
  then: function(){

  defineRule("Rele_control", { 
    whenChanged: "wb-adc/R1", //при изменении состояния датчика света
    then: function (newValue, devName, cellName) {        
   
      if (newValue > 800) {                         //если сопротивление датчика меньше  500,
          dev["wb-gpio"]["EXT1_R3A5"] = 0;            //установи на выходе wb-gpio устройство EXT1_R3A1  в состояние "выключено"            
        } else if (newValue < 1550) {                 //иначе если сопротивление датчика больше 1550, (обеспечиваем гистерезис)
          dev["wb-gpio"]["EXT1_R3A5"] = 1;            //установи EXT1_R3A1  в состояние "включено"
        }
} 
      })
}
});
///

cron в вашем случае не нужен, используйте определение дня недели

попробуйте как то так

    defineRule("Rele_control", { 
      whenChanged: "wb-adc/R1", //при изменении состояния датчика света
      then: function (newValue, devName, cellName) {
      // получаем день недели
      var mydate = new Date(); 
      var day = mydate.getDay(); // получаем номер дня недели
      var isWeekend = (day == 6) || (day == 0);    // 6 = Saturday, 0 = Sunday, должно вернуть true в случае 6 или 0
      if ( isWeekend ) { // если true (если выходной день)
        if (newValue > 800) {                         //если сопротивление датчика меньше  500,
          dev["wb-gpio"]["EXT1_R3A5"] = 0;            //установи на выходе wb-gpio устройство EXT1_R3A1  в состояние "выключено"            
        } else if (newValue < 1550) {                 //иначе если сопротивление датчика больше 1550, (обеспечиваем гистерезис)
          dev["wb-gpio"]["EXT1_R3A5"] = 1;            //установи EXT1_R3A1  в состояние "включено"
        }
      } else {  // будний день
         log("something");
     }
    });
1 лайк

Огромное спасибо! Всё получилось. Теперь пишу правило, чтоб в рабочие дни днём и ночью
температуру в доме снижало, а в выходные - держало ровно (20 … 22 град.) весь день. Без Вашей помощи долго пришлось бы мучиться: много мелких нюансов, которые мало где описаны.
Вообще-то у меня уже по этому принципу (переменная date) написан блок регулировки отопления по
рабочим дням., (разбил день на отдельные промежутки времени - startDate., end Date., как в примерах…)
но не знал как там ввести дни недели… Теперь кирпичики складываются в единое целое.
Ещё раз спасибо!

Предыдущий аналогичный тред: тут.

1 лайк

Читал., смотрел. Весьма ценная ифа.

И снова здравствуйте! (С - не помню кто…) :grinning:
Не поможет ли кто решить задачу: нужно вручную изменить/отменить выполнение правила.
Поясняю: температура в доме держится 18-20 град., уезжаю на неделю - две., ставлю виртуальный переключатель в режим “никого нет дома” - температура поддерживается 5-10 град. Что-то в примере не могу такого добиться. :worried:

код:

// Создаём виртуальное устройство - выключатель.
defineVirtualDevice("simple_test", {
  title: "Simple switch",
  cells: {
    enabled: {
      type: "switch",
      value: false
    },
  }
});

defineRule("heater_control", { //название правила - "контроль обогревателя", может быть произвольным
  whenChanged: "wb-adc/R1", //при изменении состояния датчика света
  //  whenChanged: "simple_test/enabled",
  then: function(newValue, devName, cellName) { //выполняй следующие действия

    if (dev["Simple_test"] = 1) {

      if (dev["wb-adc"]["R1"] > 800) { //если сопротивление датчика больше 800,
        dev["wb-gpio"]["EXT1_R3A6"] = 0; //установи на выходе wb-gpio устройство EXT1_R3A5  в состояние "выключено"

      } else { // иначе
        if (dev["wb-adc"]["R1"] < 1000) { //если сопротивление датчика больше 1550, (обеспечиваем гистерезис)
          dev["wb-gpio"]["EXT1_R3A6"] = 1; //установи EXT1_R3A1  в состояние "включено"       
        }
      }
    }
  }

});

Где почитать., куда покопать? Может кто делал что-то подобное? Спасибо.

Попробовать заменить dev[“Simple_test”] на dev[“Simple_test/enabled”]

Не работает оно так, формат

 dev["Simple_test"]["enabled"]

Пробовал и тот и этот варианты… не прокатывает.
Обратил внимание, что в закладке кроме виртуального переключателя, где заголовок Simple switch, имеется свойство enabled, которое можно менять переключателе on/off.,появилось устройство Simple_test, где так же есть свойство enabled, которое показывает в окошечке “0” и оно не доступно для изменения… Что-то мнится мне - где-то тут собака порылась. Может не правильно у меня виртуальный выключатель создался?

Помогает почистить лишнее (mqtt-delete-retained), а еще у меня не всегда правила применяются после сохранения. Закономерность пока не уловил, но было несколько случаев, когда сохраняешь правило, а оно не работает. Перезагрузка сервиса или всего wb решает проблему…

1 лайк

Спасибо., перезагрузка не помогла… Сейчас разбираюсь с mqtt-delete-retained. Какие ключи, чего писать… Боюсь чё-нить лишнего “завалить” (был претедент - пришлось перезаливать систему…)

Нужно найти все созданные устройства
mosquitto_sub -v -t /devices/# | grep -i Simple
а затем удалить все созданные (они будут автоматически пересозданы при сохранении скрипта или перезапуске движка правил)
что-то типа
mqtt-delete-retained /devices/Simple_test/#

дальше проще всего пойти в свой скрипт, что-то в нем поменять (пробел добавить) и сохранить. Устройство будет пересоздано.

Всё лишнее удалил., сейчас опять вернулся к скрипту. “Торкаю” его в разных вариантах…

Попробуйте вставлять отладку в разные места скрипта. Пример:
log(“script loaded”);

Опа… а это уже что-то новенькое для меня… (Сам не программист… :frowning: ) Что я должен увидеть в месте где log(“script loaded”) ?

  1. Самое простое. Поставьте эту строчку в конец Вашего скрипта. Откройте значок с гаечным ключом справа внизу. Появится консоль. Сохраните скрипт. В консоле появится надпись вида:

    2016-04-09 08:29:30script loaded

  2. Поставьте другие сообщения в разные места Вашего скрипта и смотрите, что когда вызывается…

1 лайк

Понятно. Спасибо огромное. Потихоньку начинают “осмысляться” непонятные “кракозяблы” на импортном языке… Интересно., захватывает … Но меня прямо " с корнем выдирают" из-за компа. (Занимаюсь на работе…) Придётся пока на этом остановиться. Продолжу попозже. Ещё раз огромное спаибо за ликбез…
До встречи !

1 лайк

Спасибо всем за помощь и понимание. Сегодня таки заработал виртуальный выключатель правила. Код примерно такой:

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

defineRule("heater_control", { //название правила - "контроль обогревателя"
  whenChanged: "wb-adc/R1", //при изменении состояния датчика света
  then: function(newValue, devName, cellName) { //выполняй следующие действия
    if (dev.simple_test.enabled) { // если вируальн. устр-во simple_test  в положении enabled    
      if (dev["wb-adc"]["R1"] > 800) { //если сопротивление датчика больше 800,
        dev["wb-gpio"]["EXT1_R3A6"] = 0; //установи на выходе wb-gpio устройство EXT1_R3A5  
        //в состояние "выключено" 
      } else { // иначе
        if (dev["wb-adc"]["R1"] < 1000) { //если сопротивление датчика больше 1550,
          //(обеспечиваем гистерезис)
          dev["wb-gpio"]["EXT1_R3A6"] = 1; //установи EXT1_R3A1  в состояние "включено" 
        }
      }
    }
  }
});

Наверное криво, что-то может не правильно., но работает. Ещё раз спасибо за помощь!