Настройка правильной реакции на Zigbeee2MQTT в Rules

Здравствуйте! Вопрос аналогичен Настройка правильной реакции на MQTT в Rules , но есть отличие. Там это решилось чтением топика /on, но почему-то это не работает в zigbee2mqtt. У меня есть zigbee выключатели, которые шлют тип нажатия, например, single_left. double_right, и так далее.

Мне нужно, чтобы при нажатии срабатывало правило. Но вот такая конструкция не работает:

trackMqtt("/devices/0x54ef441000ee5ba5/controls/action/on", function(message){
      log("1 switch 1 button pressed");
      if (dev[z2m_id]["action"] == "single_left"){
        if (dev["wb-mr6c_45"]["K1"] == "1"){
          dev["wb-mr6c_45"]["K1"] == "0"
        } else if (dev["wb-mr6c_45"]["K1"] == "0"){
          dev["wb-mr6c_45"]["K1"] == "1"
        }
      } else if (dev[z2m_id]["action"] == "single_right"){
        dev[intesis_name + "/Power"] = true
        dev[intesis_name + "/Mode"] = 0
      }
});

Как мне сделать такое правило, которое будет срабатывать каждый раз при приходе статуса, и не будет срабатывать при перезагрузке rules/mqtt?

Добрый день.

Рекомендую подписаться на топик данного устройства и проверить, какие данные приходят при нажатии клавиши. После этого можно настроить реакцию на изменения в топике.

Например, жмём один раз на левую клавишу, приходит single_left. Жмём ещё раз - в этот же самый топик приходит то же самое single_left. Между ними нет никакого промежуточного значения, в топике всегда лежит последнее действие. Соответственно, значение топика не меняется в этом случае, а мне нужно выполнять действие при каждом нажатии.

Нашёл на форуме схожие темы, попробую этот вариант:

Добрый день,

Буду ждать обратной связи.

Ну, тут еще и при начале работы скрипта неплохо бы топик чистить.

Добрый день, удалось ли решить вопрос?

Пока не было выездов на этот объект. Как доедем - отпишусь

Что-то пока не получается. Вот такой тестовый скрипт у меня:

devTopick="0x54ef441000ee5ba5/action";

defineRule("Switch_action", {
  whenChanged: devTopick, //при публикации
  then: function (newValue, devName, cellName) { //выполняй следующие действия
    log.info("cleaning", newValue)
    if (newValue!=null){
      dev[devTopick]="";
    }
  }
});

Но срабатывает как-то через раз, и я даже не могу понять какую-либо зависимость…


ЧЯДНТ?

Добрый день, жду ответа

Добрый день,

Код выглядит корректно, но, судя по логу, значение не изменяется, поэтому правило не срабатывает. Рекомендую подписаться на топик и проверить, как происходит запись. Возможно, пустое значение не успевает записаться, а так как новое значение совпадает с текущим в топике, правило не срабатывает.

Также прикрепляю полезную статью по wb-rules, где можно найти примеры и пояснения:
Просмотр и выполнение правил в wb-rules.

Вот так?

root@wirenboard-AYVDYJBZ:~# mosquitto_sub -t '/devices/0x54ef441000ee5ba5/controls/action' -v
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action (null)
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action (null)
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action (null)
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action (null)
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action (null)
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left

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

Попробуйте такой вариант

defineRule("Switch_action", {
  whenChanged: "/devices/0x54ef441000ee5ba5/controls/action", // При изменении MQTT-топика
  then: function (newValue, devName, cellName) { // Выполнять действия
    log.info("cleaning", newValue);
    if (newValue != null) {
      dev["0x54ef441000ee5ba5"]["action"] = ""; // Очистка
    }
  }
});

Так вообще работать перестало

04-03-2025 13:58:37.043	INFO: reloading file: /etc/wb-rules/aqara_cleaning.js
04-03-2025 13:57:58.653	INFO: reloading file: /etc/wb-rules/aqara_cleaning.js
defineRule("Switch_action", {
  whenChanged: "/devices/0x54ef441000ee5ba5/controls/action", // При изменении MQTT-топика
  then: function (newValue, devName, cellName) { // Выполнять действия
    log.info("cleaning", newValue);
    if (newValue != null) {
      dev["0x54ef441000ee5ba5"]["action"] = ""; // Очистка
    }
  }
});
root@wirenboard-AYVDYJBZ:~# mosquitto_sub -t '/devices/0x54ef441000ee5ba5/controls/action' -v
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_right
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left
/devices/0x54ef441000ee5ba5/controls/action single_left

@AIbot напиши правильный код чтобы при нажатии срабатывало правило.
Как сделать такое правило, которое будет срабатывать каждый раз при приходе статуса, и не будет срабатывать при перезагрузке rules/mqtt?

Так, мы ждём его ответа в эту тему, или надо ему в личку писать?

UPD: в личке оно тоже не пашет

Добрый день!

Робот очень удобен для написания правил.

Он предложил следующий код:

defineRule("Switch_action", {
  whenChanged: "0x54ef441000ee5ba5/action",
  then: function (newValue, devName, cellName) {
    if (newValue !== null) {
      log.info("cleaning", newValue);
      dev["0x54ef441000ee5ba5/action"] = "";
    }
  }
});

Рекомендую также проверить, доходят ли все нажатия до топиков.

По коду вашему всё должно работать как и планировалось. Уточните, какие временные промежутки между нажатиями?

PS
Попробуйте еще раз написать роботу в ЛС.

Ну да, всё откатилось к той ситуации, когда топик чистится лишь иногда, как тут.

Каждое нажатие на кнопку я вижу при подписке на топик, со связью всё хорошо.

Довольно большие, около секунды, может даже больше, я даю ему время подумать, не помогает.

Мы в конце прошлого года изменили работу wb-rules - было много жалоб на то, что whenChanged срабатывает при рестарте wb-rules. Теперь, если удалить топик (опубликовать “”), то на первое значение, полученное от драйвера, триггер whenChanged не сработает, что у вас и происходит. В вашем правиле опубликуйте не “”, а другое значение - начнет срабатывать на каждое нажатие. И правилом же отфильтруйте это значение.

P.s. из-за этого и старые рецепты не работают.

А еще лучше - ничего самому не публиковать, а использовать trackMqtt, как вы и делали изначально. Он триггерится на каждую публикацию. А уже в правиле отфильтровать переход из null в актуальное состояние, которое возникает при рестарте wb-rules.