Странная работа Правила с when

Добрый день. Странная работа правила с when …

Для описания сути вопроса показываю проблему на тестовом правиле

defineVirtualDevice("Test", {
  title: "Virtual_switches",
  cells: {
    "Switch1": {
	  type: "switch",
	  value: false
    }
  }
});

defineRule("Test", {
  when: function() {
    return dev["Test/Switch1"];
  },
  then: function (value, device, param) {
    log("Log " + device + " " + " " + param + " " + value);
  }
});

Суть проблемы:
При перезагрузке правила (и в том числе при перезагрузке любого другого имеющегося правила) и включенном Switch1 в лог приходят “очень интересные значения”
2024-08-08 01:20:24Log MR6C_4 Supply Voltage 23.768
2024-08-08 01:20:25Log MR6C_7 Supply Voltage 23.832
2024-08-08 01:20:26Log battery Current 0.009
2024-08-08 01:20:27Log MR6C_2 Supply Voltage 23.573
2024-08-08 01:20:27Log MR6C_5 Supply Voltage 23.715
2024-08-08 01:20:28Log MR6C_5 Supply Voltage 23.749
2024-08-08 01:20:29Log MR6C_3 Supply Voltage 23.674
2024-08-08 01:20:30Log MR6C_8 Supply Voltage 23.784

Соответственно когда сюда после перезагрузки попадает контрол с логическим значением true, function (value) становится равным true и дальнейшая логика начинает работать не правильно …

Поясните пожалуйста откуда и зачем они тут появляются

Воспроизвел, разбираюсь.

Поговорил с программистами - это штатное поведение. При первом запуске (старт wb-rules) движок должен определить, какие топики используются в правилах. Поэтому when при старте отрабатывает один раз при поступлении первого же (после чтения wb-rules данного правила) значения топика от MQTT брокера, что вы и видите в логе. После чего wb-rules связывает это правило с нужным топиком и дальше будет триггериться только на него.

Для подавляющего большинства задач, для получения данных от устройств, подключенных к контроллеру WB, лучше использовать функцию whenChanged, в которой такой особенности нет. Если необходимо использовать именно when, то в теле правила надо отфильтровать данные, не соответствющие запросу. Пример:

if ((device != 'Test") || (param != "Switch1")) {
  return;
}

К сожалению при старте wb-rules отрабатывает не один раз …, посмотрите лог после перезапуска wb-rules, один раз отрабатывает при перезапуске правила.

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

С фильтром в теле правила, тоже можно конечно

Здесь давайте подробнее. Одно правило срабатывает так, как я описал, один раз, потом должно реагировать только на изменения ‘device/param’. У меня это точно так. Если у вас несколько однотипных правил, то каждое из них сработает по разу, это штатное поведение. Если наблюдаете другое, то опишите, сколько строчек видите после рестарта wb-rules, что это за строчки, если рестартовать несколько раз, работает ли правило при переключении “Test/Switch1”, появляются ли “левые” строчки после срабатывания правила по переключению “Test/Switch1”.

  1. сколько строчек видите после рестарта wb-rules:
    |09-08-2024 13:49:58.914 |INFO: [rule info] Log Test MR6C_6 Supply Voltage 23.974|
    |—|—|
    |09-08-2024 13:49:58.836 |INFO: [rule info] Log Test MR3LV_1 Supply Voltage 23.886|
    |09-08-2024 13:49:58.762 |INFO: [rule info] Log Test MR6C_6 Supply Voltage 23.979|
    |09-08-2024 13:49:58.440 |INFO: [rule info] Log Test Supply_ventilation isMovingSwitch false|
    |09-08-2024 13:49:58.321 |INFO: [rule info] Log Test MR6C_8 Supply Voltage 23.777|
    |09-08-2024 13:49:58.270 |INFO: [rule info] Log Test power_status working on battery false|

  2. если рестартовать несколько раз:
    |09-08-2024 13:53:19.765 |INFO: [rule info] Log Test MR6C_12 Supply Voltage 23.919|
    |—|—|
    |09-08-2024 13:53:19.676 |INFO: [rule info] Log Test MR6C_4 Supply Voltage 23.741|
    |09-08-2024 13:53:19.548 |INFO: [rule info] Log Test Supply_ventilation isOpenSwitch false|
    |09-08-2024 13:53:19.334 |INFO: [rule info] Log Test zigbee2mqtt Log level debug|
    |09-08-2024 13:53:18.871 |INFO: [rule info] Log Test MR6C_4 Supply Voltage 23.76|
    |09-08-2024 13:53:18.768 |INFO: [rule info] Log Test MR6C_4 Supply Voltage 23.749|
    |09-08-2024 13:53:18.659 |INFO: [rule info] Log Test MR6C_2 Supply Voltage 23.541|

09-08-2024 13:54:08.959 INFO: [rule info] Log Test MR6C_5 Supply Voltage 23.721
09-08-2024 13:54:08.878 INFO: [rule info] Log Test battery Percentage 95
09-08-2024 13:54:08.791 INFO: [rule info] Log Test MR6C_2 Supply Voltage 23.544
09-08-2024 13:54:08.703 INFO: [rule info] Log Test network Wi-Fi 2 IP Online Status false
09-08-2024 13:54:08.379 INFO: [rule info] Log Test MR3LV_1 Supply Voltage 23.882
09-08-2024 13:54:08.273 INFO: [rule info] Log Test MR6C_8 Supply Voltage 23.775
09-08-2024 13:54:08.171 INFO: [rule info] Log Test MR6C_1 Supply Voltage 23.753

  1. работает ли правило при переключении “Test/Switch1”:
    Да, работает
    |09-08-2024 13:56:14.427 |INFO: [rule info] Log Test Test Switch1 true|
    |—|—|
    |09-08-2024 13:56:12.000 |INFO: [rule info] Log Test Test Switch1 true|

  2. появляются ли “левые” строчки после срабатывания правила по переключению “Test/Switch1”:
    Нет не появляются

Уточнил у программистов - да, могут проскочить несколько строчек. Пока у MQTT брокера не появится ваше виртуальное устройство, ваше правило будет дергаться на каждое приходящее от брокера значение. Но мой рецепт остается верен: либо используйте whenChanged (рекомендуется), либо фильтруйте приходящие значения.

Спасибо, с “рецептом” все понятно, именно так и сделал. Было интересно понять суть происходящего