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

И еще понял, что не работает последний if. В коде не правильно написал, нужно написать if (“wb-gpio/EXT3_DIR2”==false). Это для того, чтобы, если я когда штора едет вниз, нажав на кнопку вверх, она бы не отключались по таймеру в 30 секунд с правила движения вниз. Как это правильнее реализовать?

Предлагаю вот это все прописать нормально и выложить куда-нибудь на вики. Большому количеству пользователей, типа меня, нужен стандартный набор функций устройств и чтобы они нормально работали. А то мало того, что приходятся разбираться в семантике языка, так еще и дофига тонкостей логики, которые по факту элементарные, но без опыта о них даже не думаешь.

вс, 16 янв. 2022 г. в 22:10, Андрей К <andrey.kopylov.mail@gmail.com>:

Конструкция

if (dev[“wb-gpio/EXT3_DIR2]”==true)

записывается как

if (dev[“wb-gpio/EXT3_DIR2”])

А такая:

if (dev[“wb-gpio/EXT3_DIR2”]==false)

как

if (!dev[“wb-gpio/EXT3_DIR2”])

Примененная запись вида if (“wb-gpio/EXT3_DIR2”==false) не выполнится корректно, потому что “wb-gpio/EXT3_DIR2” - это не значение топика а просто контатнта строковая. Верно: dev[“wb-gpio/EXT3_DIR2”]

И, кстати, для вставки кода советую пользоваться ``` (три символа на русской букве Ё)

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

пн, 17 янв. 2022 г. в 10:07, Андрей Радионов через Wiren Board Support <info@wirenboard.ru>:

Да, исправил.
“!” - отрицание.
Подробнее - тут:
https://wirenboard.com/wiki/Wb-jscript#Условия

Здесь будет лежать последняя версия модуля для программной обработки разных нажатий (короткое, двойное, тройное, долгое нажатие, удержание):
/wb-rules-modules/module_ActionButtons.js

А здесь пример использования вместе со вспомогательными функциями:
/wb-rules/rules_Buttons.js

Предполагается, что вы обновили движок правил до версии 2.0

4 лайка

Добрый день
Необходимо по изменению СО2 датчика выдавать записанную команду ИК от WB-MIR v2
Не могу нигде найти информацию, каким образом выдавать данную команду из ячейки WB-MIR v2 и чтобы она длилась необходимое время.

defineRule(“msw3_co2”, {
whenChanged: “wb-msw-v3_62/CO2”,
then: function(newValue, devName, cellName) {
var co2_good = newValue < 600;
var co2_bad = newValue > 601;

    if (co2_good) {
        dev["wb-mir_v2_244"]["Play from ROM1"] = true;
    }
    if (co2_bad) {
       dev["wb-mir_v2_244"]["Play from ROM2"] = true;
    }
}

});

Про время - это как?

Я искренне не знаю при команде dev[“wb-mir_v2_244”][“Play from ROM1”] = true;
будет воспроизведен записанный код один раз или будет выдаваться с цикличностью, пока не будет вызвана команда отмены, например как dev[“wb-mir_v2_244”][“Play from ROM1”] = false;
поэтому и предположил, что нужно ограничивать команду по времени.

пн, 11 апр. 2022 г. в 12:26, Андрей Радионов через Wiren Board Support <info@wirenboard.ru>:

Сейчас при описанном правиле выше в истории происходит вот такая картина, при условии, что СО не меняется

пн, 11 апр. 2022 г. в 12:26, Андрей Радионов через Wiren Board Support <info@wirenboard.ru>:

А какие при этом значения CO2? Возможно, показания CO2 как раз находятся около 600 ppm, то одно условие сработает, то другое.

Вот тут описано:
https://wirenboard.com/wiki/WB-MSx_Consumer_IR_Manual#Воспроизведение_сигнала_из_постоянной_памяти


Значения менее 600 единиц.

я понял, что после выдачи записанного кода, цикличности нет.
Верна ли тогда строчка dev[“wb-mir_v2_244”][“Play from ROM1”] = true;
для выдачи записанного кода из ROM1?

Да.

Спасибо

Решил поделиться своим вариантом релизации правила для тёплого пола с двумя датчиками 1wire и интеграцией в home assistant (mqtt HVAC)
Буду рад если укажете что можно оптимизировать

var wc_floor_sensor_1= new Array();
var wc_floor_sensor_2= new Array();
var wc_floor_average_temp_1 = 0;
var wc_floor_average_temp_2 = 0;
var wc_floor_diff = 2;
 
defineVirtualDevice("wc_floor", { 
    title: "Cанузел. Теплый пол",
    cells: {
      "Уставка": {
        type: "range",
        value: 25,
        max: 35,
        order: 6
      },
      "Поддержание температуры": {
        type: "switch",
        value: false,
        order: 5
      },
      "Нагреватель": {
        type: "switch",
        value: false,
        order: 4
      },
      "Датчик_1": {
        type: "temperature",
        value: 0,
        order: 3
      },
        "Датчик_2": {
        type: "temperature",
        value: 0,
        order: 2
      },
        "Датчик": {
        type: "temperature",
        value: 0,
        order: 1
      }
	}
});

defineRule("wc_sensor_changed", {
  whenChanged: ["wb-w1/28-3c01d0757a5f","wb-w1/28-3c01d0759ed2"], 
	then: function (newValue, devName, cellName)  {
      if(newValue>10&&newValue<100&&dev["wc_floor"]["Датчик"]>10&&dev["wc_floor"]["Датчик"]<100)
      {	
          if (cellName == "28-3c01d0757a5f")
          {
            dev["wc_floor"]["Датчик_1"] = newValue;
			wc_floor_average_temp_1 = 0;
            wc_floor_sensor_1.unshift(newValue);
            for(var i = 0; i<wc_floor_sensor_1.length; ++i)
            {
                if(wc_floor_average_temp_1>10)
                {
                    wc_floor_average_temp_1 = wc_floor_average_temp_1 + wc_floor_sensor_1[i];
                }
                else
                {
                    wc_floor_average_temp_1 = wc_floor_sensor_1[i];
                }
            }
            wc_floor_average_temp_1 = wc_floor_average_temp_1/wc_floor_sensor_1.length;
            if(wc_floor_sensor_1.length>5)
            {
                wc_floor_sensor_1.pop();
            }
          }
          else if (cellName == "28-3c01d0759ed2")
          {
            dev["wc_floor"]["Датчик_2"] = newValue;
			wc_floor_average_temp_2 = 0;
            wc_floor_sensor_2.unshift(newValue);
            for(var i = 0; i<wc_floor_sensor_2.length; ++i)
            {
                if(wc_floor_average_temp_2>10)
                {
                    wc_floor_average_temp_2 = wc_floor_average_temp_2 + wc_floor_sensor_2[i];
                }
                else
                {
                    wc_floor_average_temp_2 = wc_floor_sensor_2[i];
                }
            }
            wc_floor_average_temp_2 = wc_floor_average_temp_2/wc_floor_sensor_2.length;
            if(wc_floor_sensor_2.length>5)
            {
                wc_floor_sensor_2.pop();
            }
          }        
          if(wc_floor_average_temp_1>10&&wc_floor_average_temp_2>10&&wc_floor_average_temp_1<100&&wc_floor_average_temp_2<100)
          {
              dev["wc_floor"]["Датчик"]= parseFloat(((wc_floor_average_temp_1+wc_floor_average_temp_2)/2).toFixed(2));
          }
          else if(wc_floor_average_temp_1<10||wc_floor_average_temp_1>100)
          {
              dev["wc_floor"]["Датчик"]= parseFloat(wc_floor_average_temp_2.toFixed(2));
          }
          else if(wc_floor_average_temp_2<10||wc_floor_average_temp_2>100)
          {
              dev["wc_floor"]["Датчик"]= parseFloat(wc_floor_average_temp_1.toFixed(2));
          }
      }
      else if(newValue>10&&newValue<100)
      {	
        dev["wc_floor"]["Датчик"] = newValue;
      }
    }
});

trackMqtt("/wc_floor/mode", function(message){
  if(message.value=="heat")
  {
    dev["wc_floor"]["Поддержание температуры"]=true;
  }
  else if(message.value=="off")
  {
    dev["wc_floor"]["Поддержание температуры"]=false;
  }
});

defineRule("wc_floor_heater", {
  whenChanged: ["wc_floor/Датчик","wc_floor/Поддержание температуры","wc_floor/Уставка"], 
	then: function (newValue, devName, cellName)  {
      
      log(dev["wc_floor"]["Поддержание температуры"]);
      log(dev["wc_floor"]["Уставка"]);
      log(dev["wc_floor"]["Датчик"]);
      
      if(dev["wc_floor"]["Поддержание температуры"])
      {
        publish("/wc_floor/state", "heat");
        if(dev["wc_floor"]["Уставка"]>dev["wc_floor"]["Датчик"])
        {
          dev["wc_floor"]["Нагреватель"]=true;
        }		
        else if(dev["wc_floor"]["Уставка"]<dev["wc_floor"]["Датчик"]-wc_floor_diff)
        {
          dev["wc_floor"]["Нагреватель"]=false;
        }
        else
        {
          dev["wc_floor"]["Нагреватель"]=false;
        }
      }
      else
      {
        publish("/wc_floor/state", "off");
        dev["wc_floor"]["Нагреватель"]=false;
      }
      dev["wb-mr3_48"]["K1"]=dev["wc_floor"]["Нагреватель"];
	}
});

На стороне Home Assistant

climate:
  - platform: mqtt
    name: "Санузел"
    modes:
      - "off"
      - "heat"
    mode_command_topic: "/wc_floor/mode"
    mode_state_topic: "/wc_floor/state"
    temperature_command_topic: "/devices/wc_floor/controls/Уставка"
    temperature_state_topic: "/devices/wc_floor/controls/Уставка"
    current_temperature_topic: "/devices/wc_floor/controls/Датчик"
    precision: 0.1
2 лайка

Попробовал модуль, все работает. Но есть проблема, не получается что бы по одному входу при одиночном нажатии включались два устройства.

room.ActionButtons.onButtonPress(
“wb-gpio/EXT1_DR1”,
{
singlePress: {
func: switchLedOn,
prop: [“wb-mao4_55”, “Channel 4”]
},
singlePress: {
func: switchLedOn,
prop: [“wb-mao4_59”, “Channel 1”]
}
}

);

Нужно немного иначе: один раз определить singlePress, задать в props все устройства и каналы, а в фунции switchLedOn их все переключать.
При этом функция switchLedOn, конечно, должна измениться (хотя бы потому что теперь она принимает 4 параметра), или завести для этого сценария отдельную функцию.

room.ActionButtons.onButtonPress(
“wb-gpio/EXT1_DR1”,
{
singlePress: {
func: switchLedOn,
prop: [“wb-mao4_55”, “Channel 4”, “wb-mao4_59”, “Channel 1”]
}
}

Здравствуйте. написал правило для управления WB - MR6Cv.2(ПРОШИВКА 1.17.7;ПО контроллера - testing) ,чтобы управлять ,к примеру - со входа блока 6 управлять выходом блока 15.

Вроде все работает,НО(!) медленно срабатывает(выключатель кнопочный) примерно 2-3 секунды.

Подскажите пожалуйста ,как быть.

P.S.:Можно ли как то обработать при этом тип нажатия(т.е. длинное,короткое и пр.??? спасибо

defineRule("msw4_Motion", {
    whenChanged: "wb-mr6c_12/input_2 Counter",
    then: function(newValue, devName, cellName) { 
     dev["wb-mr6c_12"]["input_2 Counter"] = newValue;
      
      if (newValue) {
           
          if (dev["wb-mr6c_36"]["K4"] == true) {
         
          dev["wb-mr6c_36"]["K4"] = false;
        
      }
        else {
        dev["wb-mr6c_36"]["K4"] = true;
        }
      } 
 
           if (newValue) {
           
          if (dev["wb-mr6c_36"]["K4"] == true) {
         
          dev["wb-mr6c_36"]["K4"] = false;
        
      }
        else {
        dev["wb-mr6c_36"]["K4"] = true;
        }
      }   
}
});

  1. По коду. 2 раза повторяется идентичная логика в конструкциях: if (newValue) { … }, зачем?
  2. Логику if … else в if (newValue) { … } оптимально заменит на: dev[“wb-mr6c_36”][“K4”] = !dev[“wb-mr6c_36”][“K4”];
  3. dev[“wb-mr6c_12”][“input_2 Counter”] = newValue; - вот это зачем?

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

defineRule("msw4_Motion", {
    whenChanged: "wb-mr6c_12/input_2 Counter",
    then: function(newValue, devName, cellName) {       
		if (newValue) {
			dev["wb-mr6c_36"]["K4"] = !dev["wb-mr6c_36"]["K4"];	
		} 
}
});
1 лайк