Правило управления шторным мотором по фазе

Добрый день! Некоторое время бьюсь с управлением шторой через wb_rules. Имею WB 8.5, wb-mr6lv c подключенным к нему приводом по фазе. В конфигурации настроил управление шторой через 1 и 2 выходы. Входы 1 и 2 управляются по мапинг-матрице для кнопок. Действия для различных типов нажатий на этих входах отключены, т.к. предложенные типы управления не устраивают. Задумка управления следующая: имеются счетчики коротких и длинных нажатий для 1 и 2 входов. При изменении счетчика короткого нажатия штора должна открываться/закрываться в зависимости от входа всего на 1 секунду. При длинном нажатии штора должна полностью открыться/закрыться также в зависимости от входа. Уже на этом этапе возникает проблема с полным открытием/закрытием. Также, если изменился счетчик длинного нажатия, и штора начала закрываться (работает без блоков с короткими нажатиями), изменение на счетчике коротких нажатий должно ее остановить. Итог: управление по коротким нажатиям на открытие/закрытие шторы на 1 секунду работает. При этом на длинное нажатие штора начинает открываться и сразу останавливается. Если убрать блоки кода с открытием/закрытием на 1 секунду, то при длинном нажатии штора начинает полностью открываться/закрываться, но короткие нажатия ее не останавливают.

defineVirtualDevice("shutterControl", {
  title: "Shutter Control",
  cells: {
    moving: {
      type: "switch",
      value: false
    },
    direction: {
      type: "text",
      value: ""
    }
  }
});

// Короткое нажатие: открытие шторы на 1 секунду
defineRule("shortOpenShutter", {
  whenChanged: "wb-mr6c_21/Input 1 Single Press Counter",
  then: function () {
    if (!dev["shutterControl/moving"]) {
      dev["wb-mr6c_21/Curtain 1 Open"] = true;
      startTicker("shortOpenTimer", 1000);
    }
  }
});

defineRule("stopShortOpen", {
  when: function () {
    return timers.shortOpenTimer.firing;
  },
  then: function () {
    dev["wb-mr6c_21/Curtain 1 Open"] = false;
  }
});

// Короткое нажатие: закрытие шторы на 1 секунду
defineRule("shortCloseShutter", {
  whenChanged: "wb-mr6c_21/Input 2 Single Press Counter",
  then: function () {
    if (!dev["shutterControl/moving"]) {
      dev["wb-mr6c_21/Curtain 1 Close"] = true;
      startTicker("shortCloseTimer", 1000);
    }
  }
});

defineRule("stopShortClose", {
  when: function () {
    return timers.shortCloseTimer.firing;
  },
  then: function () {
    dev["wb-mr6c_21/Curtain 1 Close"] = false;
  }
});

// Долгое нажатие: полное открытие шторы
defineRule("longOpenShutter", {
  whenChanged: "wb-mr6c_21/Input 1 Long Press Counter",
  then: function () {
    dev["wb-mr6c_21/Curtain 1 Open"] = true;
    dev["shutterControl/moving"] = true;
    dev["shutterControl/direction"] = "opening";
    startTicker("shutterMoveTimer", 7000);
  }
});

// Долгое нажатие: полное закрытие шторы
defineRule("longCloseShutter", {
  whenChanged: "wb-mr6c_21/Input 2 Long Press Counter",
  then: function () {
    dev["wb-mr6c_21/Curtain 1 Close"] = true;
    dev["shutterControl/moving"] = true;
    dev["shutterControl/direction"] = "closing";
    startTicker("shutterMoveTimer", 7000);
  }
});

// Остановка движения шторы по истечении полного открытия/закрытия
defineRule("stopFullMovement", {
  when: function () {
    return timers.shutterMoveTimer.firing;
  },
  then: function () {
    dev["shutterControl/moving"] = false;
    dev["shutterControl/direction"] = "";
    dev["wb-mr6c_21/Curtain 1 Open"] = false;
    dev["wb-mr6c_21/Curtain 1 Close"] = false;
  }
});

// Остановка при коротком нажатии во время полного движения
defineRule("interruptFullMovement", {
  whenChanged: [
    "wb-mr6c_21/Input 1 Single Press Counter",
    "wb-mr6c_21/Input 2 Single Press Counter"
  ],
  then: function () {
    if (dev["shutterControl/moving"]) {
      dev["wb-mr6c_21/Curtain 1 Open"] = false;
      dev["wb-mr6c_21/Curtain 1 Close"] = false;
      dev["shutterControl/moving"] = false;
      dev["shutterControl/direction"] = "";
      stopTicker("shutterMoveTimer");
    }
  }
});

Добрый день!

Ваш код построен грамотно. Основная проблема — пересечение логики коротких и длинных нажатий, а также отсутствие централизованного управления состоянием движения. Для решения этой задачи рекомендую:

— Ввести флаг блокировки коротких нажатий при активном длинном движении;
— Выполнять принудительное выключение реле перед запуском любого действия;
— Добавить дополнительные проверки в функции stopShort*, чтобы они не мешали работе длинных нажатий.

Также для улучшения и анализа кода вы можете воспользоваться нашим ИИ-помощником — просто нажмите на иконку робота в верхней части сайта.

Добрый день,

Удалось ли вам решить вопрос?

Да, вопрос решен, поправил логику с помощью помощника и все заработало правильно!