Приоритет правил defineRule

У правил defineRule есть какой-то приоритет или порядок выполнения?
Например у меня в отоплении есть датчик давления и есть датчик температуры.
Если давление выше или ниже нормы, то нужно отключить всё.
Но если правило по давлению сработало и отключило насосы, то не факт, что потом другие правила не включат их обратно.
И если давление немного колеблется, то ТЭНы будут постоянно включаться и выключаться, что не есть хорошо.
А если оно вышло за пределы и осталось неизменным, то может случиться авария.

Как назначить приоритет одних правил над другими?
В данном случае чтобы правило давления было главным.

var KotelName = "Kotel/Name";
var KotelTemperature = "wb-mai6_51/IN 1 N Temperature";
var KotelMinTemperature = 40;
var KotelTemperature10kW = 60;
var KotelTemperature8kW = 65;
var KotelTemperature6kW = 70;
var KotelTemperature4kW = 75;
var KotelTemperature2kW = 80;
var KotelMaxTemperature = 90;
var KotelPressureRawValue = "wb-mai6_51/IN 5 P Voltage";
var KotelPressure = "Kotel/Pressure";
var KotelMinPressure = 0.5;  //  0.667 В = 0.5 bar
var KotelMaxPressure = 2.8;  //  1.433 В = 2.8 bar
var KotelEmergencyRelayState = "wb-mio-gpio_70:2/IN1";   // если подаётся ток с предельного термореле котла на реле WB, то есть предельное термореле котла замкнуто
var KotelWBRelay = "wb-mio-gpio_70:4/K2";
var KotelWBRelay1 = "wb-mio-gpio_70:4/K3";
var KotelWBRelay2 = "wb-mio-gpio_70:4/K4";
var KotelWBRelay3 = "wb-mio-gpio_70:4/K5";
var KotelWBRelay4 = "wb-mio-gpio_70:4/K6";
var KotelWBRelay5 = "wb-mio-gpio_70:4/K7";
var KotelWBRelay6 = "wb-mio-gpio_70:4/K8";
var KotelABBRelayState = "wb-mio-gpio_70:2/IN12";
var KotelPumpRelay = "wb-mr6cu_76/K2";


defineVirtualDevice("Kotel", { 
    title: "Котёл",  
    cells: {
      Name: {
        title: "Название",
        type: "text",
        value: "Котёл",
      }, 
      ScheduleMode: { // режим 0-ручной 1-по расписанию с 23 вечера до 7 утра
        title: "Работа по расписанию",
        type: "switch",
        value: false,
      },
      Pressure: {
        title: "Давление",
        type: "value",
        value: "",
        units: "бар",
        precision: 2,
      },
      Temperature: {
        title: "Температура",
        type: "value",
        value: "",
        units: "deg C",
        precision: 2,
      },
  }
});

// действия при изменении давления
defineRule("KotelPressureRule", { 
  whenChanged: KotelPressureRawValue, 
  then: function (newValue, devName, cellName) {

    dev[KotelPressure] = (newValue/5-0.1)*(10/0.6667);   // пересчёт напряжения в давление и запись давления в ячейку виртуального устройства

    if ( KotelPressure <= KotelMinPressure || KotelMaxPressure <= KotelPressure) {
      // если давление не в норме, то выключаем вообще всё
      dev[KotelWBRelay] = false;         // выключаем ТЭН
      dev[KotelPumpRelay] = false;       // выключаем насос 
    }

  }
});


// действия при изменении температуры котла
defineRule("KotelTemperatureRule", { 
  whenChanged: KotelTemperature, 
  then: function (newValue, devName, cellName) {

    dev['Kotel/Temperature'] = newValue;   // запись температуры в ячейку виртуального устройства
    // Если температура выше предельной, выключаем ТЭН
    if (newValue >= KotelMaxTemperature) { 
      dev[KotelWBRelay] = false;      // выключаем ТЭН
      if ( !dev[KotelPumpRelay] ) { dev[KotelPumpRelay] = true; }    // включаем насос       
    }

    // Если температура ниже предельной, то нагреваем на всю мощность
    else if (newValue <= KotelTemperature10kW) { 
      dev[KotelWBRelay] = true;
      setTimeout( function () { dev[KotelWBRelay1] = true; }, 15000 ); 
      setTimeout( function () { dev[KotelWBRelay2] = true; }, 30000 ); 
      setTimeout( function () { dev[KotelWBRelay3] = true; }, 45000 ); 
      setTimeout( function () { dev[KotelWBRelay4] = true; }, 60000 ); 
      setTimeout( function () { dev[KotelWBRelay5] = true; }, 75000 ); 
      setTimeout( function () { dev[KotelWBRelay6] = true; }, 90000 ); 
    } 

    // Если температура между МИН и МАКС, то нагреваем. Мощность зависит от температуры. При повышении температуры на каждые 5 градусов снижаем мощность нагрева на 2кВт
    else if ( KotelTemperature10kW < newValue && newValue < KotelTemperature8kW )  { dev[KotelWBRelay6] = false; } 
    else if ( KotelTemperature8kW <= newValue && newValue < KotelTemperature6kW )  { dev[KotelWBRelay5] = false; } 
    else if ( KotelTemperature6kW <= newValue && newValue < KotelTemperature4kW )  { dev[KotelWBRelay4] = false; } 
    else if ( KotelTemperature4kW <= newValue && newValue < KotelTemperature2kW)   { dev[KotelWBRelay3] = false; } 
    else if ( KotelTemperature2kW <= newValue && newValue < KotelMaxTemperature )  { dev[KotelWBRelay2] = false; } 
  }
});


// действия при изменении состояния главного термореле бойлера
defineRule("BoilerHeatedRule", { 
  whenChanged: BoilerHeated, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 
    }   
    else { 
      dev[KotelWBRelay] = false;    // если на реле не подаётся ток, то нет смысла держать реле WB включённым
    }

  }
});




// действия при изменении состояния предельного термореле котла
defineRule("KotelEmergencyRelayStateRule", { 
  whenChanged: KotelEmergencyRelayState, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 

    }   
    else { 
      // если на реле не подаётся ток, но предельный термостат не сработал, значит нагрев отключился либо по термостату WB, либо по термостату бойлера
      if (dev[KotelABBRelayState] && dev[KotelWBRelay]) {  
        dev[KotelWBRelay] = false;    // если на реле не подаётся ток, то нет смысла держать реле WB включённым
      }
    }
  }
});


defineRule("KotelABBRelayStateRule", { 
  whenChanged: KotelABBRelayState, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 
      dev[KotelPumpRelay] = true;     // обязательно включаем насос при включении ТЭНа
    }
    else { 
      setTimeout( function () { dev[KotelPumpRelay] = false; }, 600000 );         // выключаем насос через 600 секунд (10 минут)
      if (dev[KotelEmergencyRelayState]) {   // если реле АВВ выключилось, но предельный термостат не сработал, значит нагрев отключился либо по термостату WB, либо по термостату бойлера
      }
    }

  }
});



defineRule("KotelPumpRelayRule", { 
  whenChanged: KotelPumpRelay, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 
    }
    else { 
      dev[KotelWBRelay] = false;         // если насос не работает, то надо выключить ТЭН
    }
  }
});



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

можно пример кода?

Смотрите строчку с комментарием “ПРИМЕР”

var KotelName = "Kotel/Name";
var KotelTemperature = "wb-mai6_51/IN 1 N Temperature";
var KotelMinTemperature = 40;
var KotelTemperature10kW = 60;
var KotelTemperature8kW = 65;
var KotelTemperature6kW = 70;
var KotelTemperature4kW = 75;
var KotelTemperature2kW = 80;
var KotelMaxTemperature = 90;
var KotelPressureRawValue = "wb-mai6_51/IN 5 P Voltage";
var KotelPressure = "Kotel/Pressure";
var KotelMinPressure = 0.5;  //  0.667 В = 0.5 bar
var KotelMaxPressure = 2.8;  //  1.433 В = 2.8 bar
var KotelEmergencyRelayState = "wb-mio-gpio_70:2/IN1";   // если подаётся ток с предельного термореле котла на реле WB, то есть предельное термореле котла замкнуто
var KotelWBRelay = "wb-mio-gpio_70:4/K2";
var KotelWBRelay1 = "wb-mio-gpio_70:4/K3";
var KotelWBRelay2 = "wb-mio-gpio_70:4/K4";
var KotelWBRelay3 = "wb-mio-gpio_70:4/K5";
var KotelWBRelay4 = "wb-mio-gpio_70:4/K6";
var KotelWBRelay5 = "wb-mio-gpio_70:4/K7";
var KotelWBRelay6 = "wb-mio-gpio_70:4/K8";
var KotelABBRelayState = "wb-mio-gpio_70:2/IN12";
var KotelPumpRelay = "wb-mr6cu_76/K2";


defineVirtualDevice("Kotel", { 
    title: "Котёл",  
    cells: {
      Name: {
        title: "Название",
        type: "text",
        value: "Котёл",
      }, 
      Status: {
        title: {en: 'State', ru: 'Состояние'},
        type: "value",
        value: 1,
        enum: {
          1: {en: 'Normal', ru: 'В норме'},
          2: {en: 'Warning', ru: 'Внимание'},
          3: {en: 'Crash', ru: 'Авария'}
        }
      },
      ScheduleMode: { // режим 0-ручной 1-по расписанию с 23 вечера до 7 утра
        title: "Работа по расписанию",
        type: "switch",
        value: false,
      },
      Pressure: {
        title: "Давление",
        type: "value",
        value: "",
        units: "бар",
        precision: 2,
      },
      Temperature: {
        title: "Температура",
        type: "value",
        value: "",
        units: "deg C",
        precision: 2,
      },
  }
});

// действия при изменении давления
defineRule("KotelPressureRule", { 
  whenChanged: KotelPressureRawValue, 
  then: function (newValue, devName, cellName) {

    dev[KotelPressure] = (newValue/5-0.1)*(10/0.6667);   // пересчёт напряжения в давление и запись давления в ячейку виртуального устройства

    if ( KotelPressure <= KotelMinPressure || KotelMaxPressure <= KotelPressure) {
      // если давление не в норме, то выключаем вообще всё
      dev[KotelWBRelay] = false;         // выключаем ТЭН
      dev[KotelPumpRelay] = false;       // выключаем насос 
      dev[Status] = 3;       // АВАРИЯ
    }

  }
});


// действия при изменении температуры котла
defineRule("KotelTemperatureRule", { 
  whenChanged: KotelTemperature, 
  then: function (newValue, devName, cellName) {
     
   if (dev[Status] < 3) {  /// <----- ПРИМЕР

       dev['Kotel/Temperature'] = newValue;   // запись температуры в ячейку виртуального устройства
       // Если температура выше предельной, выключаем ТЭН
       if (newValue >= KotelMaxTemperature) { 
         dev[KotelWBRelay] = false;      // выключаем ТЭН
         if ( !dev[KotelPumpRelay] ) { dev[KotelPumpRelay] = true; }    // включаем насос       
       }

       // Если температура ниже предельной, то нагреваем на всю мощность
       else if (newValue <= KotelTemperature10kW) { 
         dev[KotelWBRelay] = true;
         setTimeout( function () { dev[KotelWBRelay1] = true; }, 15000 ); 
         setTimeout( function () { dev[KotelWBRelay2] = true; }, 30000 ); 
         setTimeout( function () { dev[KotelWBRelay3] = true; }, 45000 ); 
         setTimeout( function () { dev[KotelWBRelay4] = true; }, 60000 ); 
         setTimeout( function () { dev[KotelWBRelay5] = true; }, 75000 ); 
         setTimeout( function () { dev[KotelWBRelay6] = true; }, 90000 ); 
       } 

       // Если температура между МИН и МАКС, то нагреваем. Мощность зависит от температуры. При повышении температуры на каждые 5 градусов снижаем мощность нагрева на 2кВт
       else if ( KotelTemperature10kW < newValue && newValue < KotelTemperature8kW )  { dev[KotelWBRelay6] = false; } 
       else if ( KotelTemperature8kW <= newValue && newValue < KotelTemperature6kW )  { dev[KotelWBRelay5] = false; } 
       else if ( KotelTemperature6kW <= newValue && newValue < KotelTemperature4kW )  { dev[KotelWBRelay4] = false; } 
       else if ( KotelTemperature4kW <= newValue && newValue < KotelTemperature2kW)   { dev[KotelWBRelay3] = false; } 
       else if ( KotelTemperature2kW <= newValue && newValue < KotelMaxTemperature )  { dev[KotelWBRelay2] = false; } 
  }
}});


// действия при изменении состояния главного термореле бойлера
defineRule("BoilerHeatedRule", { 
  whenChanged: BoilerHeated, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 
    }   
    else { 
      dev[KotelWBRelay] = false;    // если на реле не подаётся ток, то нет смысла держать реле WB включённым
    }

  }
});




// действия при изменении состояния предельного термореле котла
defineRule("KotelEmergencyRelayStateRule", { 
  whenChanged: KotelEmergencyRelayState, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 

    }   
    else { 
      // если на реле не подаётся ток, но предельный термостат не сработал, значит нагрев отключился либо по термостату WB, либо по термостату бойлера
      if (dev[KotelABBRelayState] && dev[KotelWBRelay]) {  
        dev[KotelWBRelay] = false;    // если на реле не подаётся ток, то нет смысла держать реле WB включённым
      }
    }
  }
});


defineRule("KotelABBRelayStateRule", { 
  whenChanged: KotelABBRelayState, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 
      dev[KotelPumpRelay] = true;     // обязательно включаем насос при включении ТЭНа
    }
    else { 
      setTimeout( function () { dev[KotelPumpRelay] = false; }, 600000 );         // выключаем насос через 600 секунд (10 минут)
      if (dev[KotelEmergencyRelayState]) {   // если реле АВВ выключилось, но предельный термостат не сработал, значит нагрев отключился либо по термостату WB, либо по термостату бойлера
      }
    }

  }
});



defineRule("KotelPumpRelayRule", { 
  whenChanged: KotelPumpRelay, 
  then: function (newValue, devName, cellName) {
    if (newValue) { 
    }
    else { 
      dev[KotelWBRelay] = false;         // если насос не работает, то надо выключить ТЭН
    }
  }
});
1 лайк

спасибо.
не думал что так просто