Синхронизация запуска wb-rules и wb-mqtt-serial

Добрый день!

Заметил одну особенность. Если мы хотим выполнить ряд комманд, например выключить и затем включить реле (нажать кнопку), отправить сиглал ИК под номером 1, а затем под номером 2, первая команда может не выполниться, или вторая может выполниться слишком быстро без должной задержки.
Это происходит при загрузке контроллера или при systemctl start wb-rules wb-mqtt-serial.
wb-rules грузится быстрее чем wb-mqtt-serial, и когда wb-rules начинает управлять оборудованием, wb-mqtt-serial еще не готово.

Этому багу больше 2 лет. Я предлагал запускать демоны в определенном порядке для исключения пердимоноклей с неготовностью, но в официальном образе пока грусть. Сделал свой скрипт, чего и Вам желаю.

С последовательным запуском скриптов в рулях пришлось поприседать куда серьезней, но тоже распедалил, чего желаю и Вам. ))

1 лайк

Недавно оптимизировал старт своего кода скриптов wb-rules и он стал быстрее с̶к̶о̶р̶о̶с̶т̶и̶ ̶с̶в̶е̶т̶а запуска wb-mqtt-serial. Придется таймаут ставить.

Можно было бы создать топик готовности wb-mqtt-serial…

1 лайк

Здравствуйте!
Также, думаю, можно при запуске правила проверять, запущен ли сервис wb-mqtt-serial. Если нет, то ждать некоторое время и снова проверять. Если запущен - то выполнять требуемые действия.

wb-mqtt-serial стартует какое-то время. Я так понимаю, если сервис только что запустили, он будет запущен, но не будет готов исполнять команды

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

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

Ну тут опять же: добавил каналов в устройства, сервис стартует дольше, лезть править таймауты. Кароче костыль на костыле получается.

Я давно предлагаю авторам разгрести эйфелеву башню (исторических?) костылей, но их представления о работоспособном продукте принципиально отличаются от моих. :upside_down_face:

Если серьезно, serial не единственный демон, который нужно синхронить с правилами. Проблему эту, как и много других, надо решать архитектурно.

1 лайк

По какому признаку это лучше делать?

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

Факт работы сервиса можно проконтролировать из правил, например, так:

 runShellCommand("systemctl is-active wb-mqtt-serial", {
      captureOutput: true,
      exitCallback: function (exitCode, capturedOutput) {
        log("cmd output: " + capturedOutput);
        if (capturedOutput == "active") {
            log("wb-mqtt-serial is active");
        }
      }
   });

Добрый день!
Подниму тему и опишу проблему еще раз.

При загрузке контроллера или при перезапуске сервисов wb-mqtt-serial и wb-rules, wb-rules пытается выполнять команды по cron или некоторые регуляции. Это может произойти раньше, чем wb-mqtt-serial создало все топики устройств (у нас отключено сохранение в БД состояния mosquitto).
Из-за этого получаю ошибку:

wb-rules[9771]: ERROR: failed to SetValue for unexisting control wb-mir_v2_224/Play from ROM2: true

Это может привести к неправильной последовательности или к пропуску части команд.

Как проверить, что определенный control уже создан и wb-mqtt-serial готово к работе?
У меня есть мысли, что теперь, когда wb-mqtt-serial чистит топики при перезапуске, есть возможность проверить те или иные признаки, например мета информацию устройства, чтобы определить, можно ли начинать управление или нет.

Здравствуйте! Какого-то штатного механизма нет. Думаю, что можно проверять с помощью trackMqtt наличие значения в топике устройства. Если оно есть, то выполнять правило.

1 лайк

Попробуем сделать

Сам лично не пробовал, но в wb-rules есть вот такая штука:

GitHub - wirenboard/wb-rules: Rule engine for Wiren Board
Для проверки контрола на существование можно воспользоваться функцией isControlExists(<id контрола>) .

Возможно, подойдёт для Вашей задачи.

Здравствуйте. Получилось решить вашу задачу?