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

Добрый
Поискал поиском- но не попалось
Вопрос следующий
Есть желание управлять освещением(через реле MR6)
Сейчас реализовал как:
однократное нажатие- включил реле
длинное- выключил
двойное- включение на время…

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

А режим с таймером уже оставить на той же кнопке с дабл…

Не подскажите- есть ли\ был ли подобный пример с правилом
Или в каком направлении копать при написании правила

Добрый день! Так чего придумывать, в реле есть такой функционал, надо просто вход настроить как кнопку без фиксации

Здравствуйте.

Вам верно подсказывают необходимо настроить режим работы “Кнопка без фиксации”.

Те этот режим будет применяться и при работе реле по правилу(любому в рамках нажатий кнопки) под управлением контроллера?

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

У меня желание управлять с кнопок вирт устройства, с физического выключателя и, в перспективе , кнопкой на брелке дистанционно( думаю zeegbe)
Плюс с физического выключателя иметь режим включения реле с задержкой на время

Те на все на это пишу правило

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

Что написал и у меня работает скинутт постараюсь

// правило управления уличным освещением

function Start_StreetLight() { // включение уличного освещения
dev[Do_StreetLight] = true; // переключить реле выхода 1
dev[‘Virt_Home’][‘OnOff2_StreetLight’] = true; // ползунок включения уличного освещения в вирт устройстве
// log(“уличное освещение старт”);
// log ("реле состояние старт: " + !dev[Do_StreetLight])
};

function Stop_StreetLight() { // выключение уличного освещения
dev[Do_StreetLight] = false; // переключить реле выхода 1
dev[‘Virt_Home’][‘OnOff2_StreetLight’] = false; // ползунок включения уличного освещения в вирт устройстве
// log(“уличное освещение стоп”);
// log ("реле состояние стоп: " + !dev[Do_StreetLight])
};

// включение уличного освещения от кнопки управления виртуального устройства или физического выключателя со входа 1
defineRule(‘On_StreetLight’, {
whenChanged: [“Virt_Home/On2”, Switch1S_StreetLight],
then: function() {
Start_StreetLight(); // включение уличного освещения кнопкой вирт устройства или выключателем
}

});

// выключение уличного освещения от кнопки управления виртуального устройства или физического выключателя со входа 1
defineRule(‘Off_StreetLight’, {
whenChanged: [“Virt_Home/Off2”, Swith1L_StreetLight],
then: function() {
Stop_StreetLight(); // выключение уличного освещения кнопкой вирт устройства или выключателем
}

});

// включение уличного освещения с задержкой на выключение от двойного нажатия кнопки выключателя

defineRule(‘StreetLight_Timer’, {
whenChanged:Swith1D_StreetLight , // при двойном нажатии кнопки выключателя
then: function (newValue, devName, cellName) {
dev[Do_StreetLight] = true; // замыкается контакты реле выход 1
// log(“уличное освещение таймер”);
dev[“Virt_Home”][“OnOff2_StreetLight”] = true; // в вирт устройстве флажок устанавливается на включено
setTimeout(function () {
dev[Do_StreetLight] = false; // размыкаются контакты реле по выходу 1
// log(“уличное освещение таймер СТОП”);
dev[“Virt_Home”][“OnOff2_StreetLight”] = false; // флажокв вирт устройсстве устанавливается на выыключено
},180000); // свет отключится через 120 секунд после нажатия кнопки выключателя

}
});

// 2.выключатель управления уличным освещением
var Switch1S_StreetLight = ‘wb-mr6c_3/Input 1 Single Press Counter’; // короткое нажатие выключателя по вводу 1
var Swith1D_StreetLight = ‘wb-mr6c_3/Input 1 Double Press Counter’; // двойное нажатие кнопки выключателя по вводу 1
var Swith1L_StreetLight =‘wb-mr6c_3/Input 1 Long Press Counter’ ;

Сейчас работает такое правило

В этом месте хотелось бы иметь не Swith1L_StreetLight, а однократное нажатие

Один из вариантов это использовать логический флаг

Создайте внутреннюю переменную, которая хранит текущее состояние реле.
Не проверять сразу mqtt-топик, а проверять флаг, а в конце функции обновлять его.
Вот примерный вариант, пробуйте адаптировать в своём коде.

var relayState = false; // текущее состояние реле

defineRule("button_relay_control", {
  whenChanged: "wb-gpio/EXT1_IN1", // кнопка
  then: function (newValue) {
    if (!newValue) return; // реагируем только на нажатие

    if (!relayState) {
      dev["wb-mr6c_12"]["K1"] = true;
      relayState = true;
      log("Реле включено");
    } else {
      dev["wb-mr6c_12"]["K1"] = false;
      relayState = false;
      log("Реле выключено");
    }
  }
});

Ещё вариант делегировать “toggle” виртуальному устройству

Если ты хотите управлять этим же реле и с MQTT, и с брелка, и с физической кнопки,
удобно завести виртуальное устройство с параметром “toggle”,
а в правилах обрабатывать все источники одинаково:

defineVirtualDevice("relay_control", {
  title: "Реле с разных источников",
  cells: {
    Toggle: { type: "pushbutton", value: false }
  }
});

defineRule("toggle_handler", {
  whenChanged: "relay_control/Toggle",
  then: function() {
    dev["wb-mr6c_12"]["K1"] = !dev["wb-mr6c_12"]["K1"];
  }
});

// физическая кнопка просто вызывает тот же toggle
defineRule("button_call_toggle", {
  whenChanged: "wb-gpio/EXT1_IN1",
  then: function(newValue) {
    if (newValue) dev["relay_control"]["Toggle"] = true;
  }
});

Ок, буду пробовать
Спасибо

Добрый день.

Если у вас остались вопросы к технической поддержке - пишите, постараемся помочь.

только сегодня добрался до машины

написал так

defineVirtualDevice(“relay_control”, {
title: “Реле с разных источников”,
cells: {
Toggle: { type: “pushbutton”, value: false }
}
});

defineRule(“toggle_handler”, {
whenChanged: “relay_control/Toggle”,
then: function() {
dev[“wb-mr3_2”][“K1”] = !dev[" wb-mr3_2"][“K1”];
log (“старт виртуальная”);
log ("кнопка состояние вирт старт: " + dev[“relay_control”][“Toggle”]);
log ("реле состояние физическое старт вирт кнопка: " + !dev[“wb-mr3_2”] [“K1”]);

}
});

// физическая кнопка просто вызывает тот же toggle
defineRule(“button_call_toggle”, {
whenChanged: “wb-mr3_2/Input 1 Single Press Counter”,
then: function(newValue) {
if (newValue) dev[“relay_control”][“Toggle”] = true;
log (“физ кнопка”);
log ("реле состояние физическое: " + !dev[“wb-mr3_2”] [“K1”]);
log ("реле состояние вирт: " + dev[“relay_control”][“Toggle”]);
}
});

Что получил
При нажатии вирт кнопки:

2025-11-13 23:13:45

старт виртуальная

2025-11-13 23:13:45

кнопка состояние вирт старт: true

2025-11-13 23:13:45

реле состояние физическое старт вирт кнопка: false

Физически лампа включается

Потом нажимаю физическую кнопку:

2025-11-13 23:14:10

физ кнопка

2025-11-13 23:14:10

реле состояние физическое: false

2025-11-13 23:14:10

реле состояние вирт: true

2025-11-13 23:14:10

старт виртуальная

2025-11-13 23:14:10

кнопка состояние вирт старт: true

2025-11-13 23:14:10

реле состояние физическое старт вирт кнопка: true

Лампа при нажатии кнопки выключается на долю секунды, потом включается
По логам понимаю, что правило зациклилось?
Или я его не верно переписал?

Кроме того
кнопка в вирт устройстве

это кнопка позволяющая полноценно управлять реле?
В моем случае она только включает реле, и повторно никаких действий с ней не осуществить нельзя

Здравствуйте.
У вас между кавычками " wb-mr3_2" стоит пробел.
Контроллер пытается прочитать несуществующее устройство " wb-mr3_2" → возвращает undefined, → !undefined = true.
Из-за этого реле всегда включается, а не переключается.

Примерно так будет корректнее:

  title: "Реле с разных источников",
  cells: {
    Toggle: { type: "pushbutton", value: false }
  }
});

// --- единый переключатель ---
defineRule("toggle_handler", {
  whenChanged: "relay_control/Toggle",
  then: function () {

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

    // переключение
    dev["wb-mr3_2"]["K1"] = !state;

    log("toggle: новое состояние " + !state);
  }
});

// --- физическая кнопка вызывает тот же toggle ---
defineRule("button_call_toggle", {
  whenChanged: "wb-mr3_2/Input 1 Single Press Counter",
  then: function (newValue) {

    // реагируем только на повышение счётчика
    if (newValue)
      dev["relay_control"]["Toggle"] = true;

    log("физическая кнопка нажата");
  }
});

Ок, поправлю, буду внимательнен

Еще
“Toggly”- это стандартная команда js?
Не могу найти описанин

Toggle это логика переключения, можно адаптировать полностью под ON/OFF, без toggle, без зацикливаний, без двойных вызовов.
Логика будет примерно такой:

  • Виртуальное устройство имеет два pushbutton: ON и OFF
  • Есть индикатор состояния (switch)
  • Виртуальная ON включает реле
  • Виртуальная OFF выключает реле
  • Физическая кнопка переключает реле, но состояние синхронизируется с виртуальным устройством
  • Всё работает чисто и без циклов

да, спасибо
все отрабатывает

логика понятна
она позволяет отработать правило в рамках уже существующего вирт устройства

те не true или falls, а записать так: dev[“wb-mr3_2”][“K1”] = !dev[" wb-mr3_2"][“K1”] ?

Должно выглядеть примерно так

// --- виртуальное устройство ---
defineVirtualDevice("relay_control", {
  title: "Реле с разных источников",
  cells: {
    On:  { type: "pushbutton", value: false },
    Off: { type: "pushbutton", value: false }
  }
});
// --- обработчик кнопки ON ---
defineRule("relay_on_handler", {
  whenChanged: "relay_control/On",
  then: function (v) {

    if (!v) return;            // кнопка pushbutton → реагируем только на true

    dev["wb-mr3_2"]["K1"] = true;
    log("команда: включить реле");
  }
});
// --- обработчик кнопки OFF ---
defineRule("relay_off_handler", {
  whenChanged: "relay_control/Off",
  then: function (v) {

    if (!v) return;

    dev["wb-mr3_2"]["K1"] = false;
    log("команда: выключить реле");
  }
});
// --- физическая кнопка: одинарное нажатие = ВКЛ ---
defineRule("button_single_press", {
  whenChanged: "wb-mr3_2/Input 1 Single Press Counter",
  then: function (v) {

    if (!v) return;          // реагируем на рост счётчика

    dev["relay_control"]["On"] = true;
    log("физическая кнопка: ОДИНОЧНОЕ — включить");
  }
});
// --- физическая кнопка: двойное нажатие = ВЫКЛ ---
defineRule("button_double_press", {
  whenChanged: "wb-mr3_2/Input 1 Double Press Counter",
  then: function (v) {

    if (!v) return;

    dev["relay_control"]["Off"] = true;
    log("физическая кнопка: ДВОЙНОЕ — выключить");
  }
});

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

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

Может что типа switch использовать?

// --- виртуальное устройство ---
defineVirtualDevice("relay_control", {
  title: "Реле с разных источников",
  cells: {
    On:  { type: "pushbutton", value: false },
    Off: { type: "pushbutton", value: false }
  }
});
// --- единая функция, куда сводим все вызовы ---
function relayCommand(source) {

  switch (source) {

    case "on":
      dev["wb-mr3_2"]["K1"] = true;
      log("команда: ВКЛ (src: " + source + ")");
      break;

    case "off":
      dev["wb-mr3_2"]["K1"] = false;
      log("команда: ВЫКЛ (src: " + source + ")");
      break;

    default:
      log("неизвестная команда: " + source);
  }
}
// --- обработчик виртуальной кнопки ON ---
defineRule("relay_control_on", {
  whenChanged: "relay_control/On",
  then: function (v) {
    if (v) relayCommand("on");
  }
});
// --- обработчик виртуальной кнопки OFF ---
defineRule("relay_control_off", {
  whenChanged: "relay_control/Off",
  then: function (v) {
    if (v) relayCommand("off");
  }
});
// --- физическая кнопка: одинарное нажатие = ВКЛ ---
defineRule("button_single_press_sw", {
  whenChanged: "wb-mr3_2/Input 1 Single Press Counter",
  then: function (v) {
    if (v) relayCommand("on");
  }
});
// --- физическая кнопка: двойное нажатие = ВЫКЛ ---
defineRule("button_double_press_sw", {
  whenChanged: "wb-mr3_2/Input 1 Double Press Counter",
  then: function (v) {
    if (v) relayCommand("off");
  }
});

Я хотел бы написать правила при котором

  • ВКЛ при однократном нажатии

И при следующем однократном нажатии этой же кнопки реле отключалось

т.е не

-(тут ВЫКЛ при двойном)

А пытаюсь ВКЛ и потом ВЫКЛ при одинарном

Те

  • включилось

При последующем

выключилось

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