Включение\выключение реле однократным нажатием

Как вам например тумблер по одинарному нажатию (single press → toggle)

defineRule("button_single_press_toggle", {
  whenChanged: "wb-mr3_2/Input 1 Single Press Counter",
  then: function (cnt) {
    // реакция только на рост счётчика
    if (!cnt) return;

    // инверсия состояния реле
    var state = dev["wb-mr3_2"]["K1"];
    dev["wb-mr3_2"]["K1"] = !state;

    log("single press → toggle: новое состояние K1 = " + !state);
  }
});

Работает примерно так

Single Press Counter увеличивается на 1 при каждом однократном нажатии.

Например: 1 → 2 → 3 → 4 → …

Каждый раз правило срабатывает один раз и просто делает:

K1 = !K1

Поэтому результат:

  • нажал → включилось
  • ещё раз нажал → выключилось
  • ещё раз → включилось
  • и т.д.

Если дополнительно управлять реле через виртуальные кнопки ON/OFF
То код примерно такой:

defineVirtualDevice("relay_control", {
  title: "Реле",
  cells: {
    On:  { type: "pushbutton", value: false },
    Off: { type: "pushbutton", value: false }
  }
});

defineRule("relay_on", {
  whenChanged: "relay_control/On",
  then: function(v) {
    if (v) dev["wb-mr3_2"]["K1"] = true;
  }
});

defineRule("relay_off", {
  whenChanged: "relay_control/Off",
  then: function(v) {
    if (v) dev["wb-mr3_2"]["K1"] = false;
  }
});

Спасибо!!
этот вариант отрабатывает именно так как хотелось
Мало того- он помог убрать косяк моих устройств небольшой
Пока едет ZeegBe брелок- подключил имеющийся брелок 866мгц от Zonta
Пока кнопка на зонт, а он уже через реле с коротким нажатием как эмуляция нефиксируемой кнопки выключателя
Но ранее был косяк- свет таким образом можно было только включить с брелка, а выключать по двойному не получалось

Теперь же логика вкл- выкл однократным нажатием этот косяк сняла и брелок отрабатывает как и должен
Плюс добавил небольшой код для таймера- он в ваш вариант вписывается и работает как задуман
Спасибо за терпение)

Если позволите последний вопрос-

return- понятно, останавливает выполнение правила
В части короткой записи (v) или (!cnt)- просто краткое условное наименование функции и в этом месте может быть что угодно?

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

Добрый день.
v - это имя входного аргумента функции, куда WB передаёт новое значение ячейки, которое вызвало правило.

Можно назвать его как угодно, работать будет одинаково:

then: function(value) { ... }

или:

then: function(x) { ... }

или вообще:

then: function(newValue) { ... }

Важное замечание для виртуальных pushbutton:

  • true — нажали кнопку
  • false — отпустили (уже через пару миллисекунд)

Поэтому чаще проверяют только на true:

if (v) { ... }

Замечание для счётчиков Single Press / Double Press / Long Press:

WB передаёт число, которое возможно увеличилось:

1 → 2 → 3 → 4 → …

Мы проверяем вызов только по росту значения:

if (!cnt) return; // cnt == 0 → не реагируем

На самом деле можно было бы написать:

if (cnt > 0) {
    // делаем действие
}

Но для меня привычный паттерн в WB-скриптах:

if (!cnt) return;

Спасибо
забрал, пошел учить матчасть)