Не работает правило с датчиком WB-MIR v.2

Добрый день! Прошу помощи в создании правила. При повышении температуры более 25 градусов на zigbee датчике, послать команду на включение кондиционера (Play from ROM1) датчика WB-MIR v.2.
Подписался на топик “/devices/wb-mir_v2_148/controls/Play from ROM1”, вижу, что при нажатии в веб- интерфейсе контроллера Play from ROM1, публикуется значение 1 потом 0. В связи с чем написал следующее правило:

defineRule({
  whenChanged: "Temperature/temperature",
  then: function (newValue, devName, cellName) {
    if (newValue > "25") {
	dev["wb-mir_v2_148/Play from ROM1"] = 1}
  }
});

Итог: правило не срабатывает, значение автоматически в топике не публикуется. Форум заранее просмотрел, что именно публиковать в топик не нашел.

Смущает вот эта запись. Здесь вы сравниваете значение в newValue с ТЕКСТОМ 25.
Видимо вы хотели сравнить с ЧИСЛОМ 25 ? В этом случае уберите двойные кавычки (признак текстового значения).
if (newValue > 25)

Включайте для отладки вывод в log(); промежуточных шагов и значений - это упростит понимание что и где происходит не так, как вы планировали.
Например

...
then: function (newValue, devName, cellName) {
     log("Сработало правило по факту изменения топика Temperature/temperature");
     log("Получено значение  newValue =  ", newValue );
     log( "переменная newValue имеет тип : ", typeof(newValue));
     if (newValue > 25) {
         log( "выполнилось логическое условие:  newValue > 25" );
         dev["wb-mir_v2_148/Play from ROM1"] = 1}
  }
....

PS
Дополню: Если newValue действительно получает текстовое значение температуры (мало ли), то перед сравнением полученного текста с числом 25 необходимо будет преобразовать текстовую переменную в число и только потом сравнивать числа логическим оператором в if.

С этой частью правила

defineRule({
  whenChanged: "Temperature/temperature",
  then: function (newValue, devName, cellName) {
    if (newValue > "25") {

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

Вы писали

Но если вы уверены (и проверили это), что правило работает, то это хорошо.
Тогда, если я понял вас верно, у вас “не срабатывает” не все правило, а только

dev["wb-mir_v2_148/Play from ROM1"] = 1;

Если в имени топика нет опечатки, то стоит сделать вот так:

dev["wb-mir_v2_148/Play from ROM1"] = true ;

1 лайк

Полностью согласен. Присваивать логической переменной числовое значение - плохо.

Спасибо!

dev["wb-mir_v2_148/Play from ROM1"] = true ;

Опечатку исправил, помогло!
Произошла не предусмотреная мною проблемма) теперь команда при превышении температуры на включение кондиционера посылается постоянно (пока температура не снизится). Можно ли дописать скрипт с учетом единоразовой посылки команды при превышении заданной температуры?

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

Например вот так (или также, но в качестве флага использовать контрол виртуального устройства - это будет нагляднее ):

  • если температура выше 25 и сейчас кондиционер выключен → включи кондиционер и измени статус на “включен”
  • если температура упала ниже 22 (для примера) и кондиционер сейчас работает → выключи его и установи его статус как “выключен”
    В остальных случаях - ничего не предпринимай (исключаем повторные посылы дублирующих команд)
var CoоlingState = false; // текущее состояние кондиционера (вкл или выкл), начальное значение при запуске контроллера

defineRule({
  whenChanged: "Temperature/temperature",
  then: function (newValue, devName, cellName) {

    if ( (newValue > 25) & (CoоlingState == false) ) {  // температура выше 25 и сейчас кондиционер выключен
       dev["wb-mir_v2_148/Play from ROM1"] = true;      // команда включить кондиционер 
       CoоlingState = true; }                           // установить флаг "кондиционер включен"

    if ( (newValue < 22) & (CoоlingState == true) ) {   // температура ниже 22 и сейчас кондиционер включен
       dev["wb-mir_v2_148/Play from ROMХ"] = true;      // команда выключить кондиционер 
       CoоlingState = false; }                          // установить флаг "кондиционер включен"

  }
});

PS текст правила писал здесь в живую (без проверки синтаксиса, надеюсь нигде не опечатался) - проверьте его или напишите сами

PPS У такого решения тоже есть недостатки - если команда IR не дошла до кондиционера (например, скрипт послал команду выключить кондиционер и для себя помечает кондиционер как выключенный, а по факту сам кондиционер по каким-то причинам продолжает работу, то скрипт больше уже не будет пытаться его выключить и кондиционер останется работать “вечно” :slight_smile:
Поэтому стоит предусмотреть и другие варианты анализа текущего состояния кондиционера или хотя бы регулярно (допустим 1 раз в час) посылать принудительно повторную команду кондиционеру с текущим статусом (если логически он “выключен”, то пошли еще раз “выключить”)

1 лайк

Да, видел что увязывают контроль работы кондиционера на контроль потреблемой им мощности (ставят на линию питания токовый трансформатор и подключают на канал измерителя).
Суммарно затраты на оборудование, конечно, еще не приближаются к цене на шлюз, например от Onokom - но если оценить еще и работу по настройке - то шлюз получается просто дешевле.