Проблема с порядком запуска wb-rules и wb-mqtt-serial

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

Столкнулись с проблемой, сейчас wb-rules запускается до того, как wb-mqtt-serial активирует все устройства. Из-за этого правила могут выполняться в момент, когда необходимые устройства ещё недоступны.

Нужно, чтобы wb-rules запускался только после полной активации всех устройств, которые поднимает wb-mqtt-serial. Возможно, в systemd есть механизм, позволяющий сервису становиться активным не просто после запуска, а когда он сам решит, что завершил все необходимые действия.

ChatGPT предлагает такой пример сервиса на bash:

#!/bin/bash

# Используем systemd-notify для оповещения systemd о статусе
SYSTEMD_NOTIFY=/usr/bin/systemd-notify

# Оповещаем systemd, что сервис запускается
$SYSTEMD_NOTIFY --ready=false
echo "Waiting for devices to be ready..."

# Пример проверки (можно заменить на логику, которая действительно проверяет готовность устройств)
while ! some_command_to_check_devices_ready; do
    echo "Devices not ready, waiting..."
    sleep 5
done

echo "Devices are ready, notifying systemd"
$SYSTEMD_NOTIFY --ready

# Держим сервис активным (если это требуется)
exec sleep infinity

Полагаю имеет смысл встроить похожий механизм в службу wb-mqtt-serial, чтобы она становилась активной после инициализации всех устройств. И указать сервису wb-rules её в качестве зависимостей для запуска.

1 лайк

Добрый день.
Если выбранное решение вас устраивает - то хорошо.
Но, позволю себе пару замечаний.
Первое: а по какому признаку считать что wb-mqtt-serial полностью запустился? А если он запустился - но часть устройств в аварии и недоступны? Или - а если сервис был перезапущен в процессе работы?

Второе: как показывает практика рассчитывать на порядок запуска и строить зависимости - чревато тем что в итоге будут циклические зависимости.

Обычно пишут все ж скрипты, которые запускают правила только если контрол-источник существует и его /meta/error пуст. И соответственно останавливает при переходе в нештатное состояние.

Мое предложение считать wb-mqtt-serial полностью запущенным после создания устройств в соответствии с MQTT Conventions. На этом этапе сторонние скрипты смогут отслеживать доступность устройств через /meta/error.

После запуска сервис wb-mqtt-serial будет находиться в состоянии activating. Как только все устройства будут созданы в MQTT, сервис перейдет в состояние active.

Получится Вам реализовать такое?

Текущие зависимости wb-rules:
After=wb-hwconf-manager.service wb-modules.service mosquitto.service

На практике wb-rules не работает без полностью запущенной службы wb-mqtt-serial (к слову сказать mosquitto использует механизм notify, чтобы менять свое состояние) и пользователи скрипта wb-engine неоднократно сообщали о данной проблеме.

Отнюдь, работает. И далеко не всегда (не всем) движку правил вообще нужны топики wb-mqtt-serial.
Да, можно именно такой скрипт написать, который не сможет корректно запуститься при недоступности какого-то топика, но по мне. Но проще именно в скрипте проверять.

В текущем виде скрипт не видит устройства (потому что на момент запуска их нет в MQTT) и не пробрасывает их дальше в HA. Вы на первую часть сообщения не ответили, есть возможность реализовать смену состояний у службы wb-mqtt-serial? Дальше уже пользователи сами смогут решить, ставить ли эту службу в зависимость или нет.

Ну, в общем “напрямую” - нет. Флагом готовности сервиса к работе может служить его способность отвечать на RPC запросы, например.

Не “из-за этого”. Проблема в том, что устройство, опрашиваемое wb-rules, недоступно. И только в этом. А причины этого: помехи на шине, физически отвалилось … не запущен wb-mqtt-serial … их много.

Имхо, скрипты, чувствительные к результату, обязаны использовать топик error

То есть только вот это использовать.В самом скрипте учитывать доступность.
Иначе, … например, в момент срабатывания правила устройство недоступно (красное) или недоступен зависимый топик … в этом случае будет ошибка wb-rules

Использование топика error делает правило отказоустойчивый" по любым причинам.
И плохо, что это не рассмотрено в примерах правил в документации, наверное.

Имхо.

Подпишусь под этими словами. В типичном скрипте большая часть кода - это проверки входных параметров, в общем.

Ну, примеры-то для начинающих, они демонстрируют основы. И про ошибки там есть.

Поэтому, “наверное” …
Да и, основная документация не в справке, а там все нормально расписано.

Но обычно все начинается с copy/paste, править под себя и … не учитываются важные моменты (тот же error, некоторые стартовые моменты …). Особенно “начинающими”.

Ну, я всегда, когда что-то пишу перед тем как ту же функцию писать думаю: а что если на вход вместо ожидаемого float придет указатель на строковый массив? А если null?
Offtop: ошибка в типах - это вообще классика, особенно в скриптах, в которых автоприведение часто работает как надо. А редко, но больно - как покажется интерпретатору правильным.

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

Я пробовал описать это: Написание скриптов для начинающих — Wiren Board

Точно это про “начинающего”?

Вот тут согласен. (И вообще многих языков программирования касается - везде есть особенности.

Но в случае с автоматизацией дома, это еще и … безопасность.
И тут очень много факторов.

Это далеко не так. А некоторые вопросы, не только тут на форуме, … прямо хочется вместо ответа послать сначала изучить теорию или к разработчику (вы к интеграторам посылаете).

Все там хорошо написано.
Но, имхо, все примеры кода с конкретной логикой все равно должны быть максимально “безопасными”, обернутыми в максимальное число проверок (даже если это не очень нужно) … чтобы “начинающий” понял как “правильно”, и потом уже на свой страх и риск переделал и максимально упростил.

Но это все имхо (личное мнение), написание документации отнимает не мало времени …

Хорошо, я понял, все кто будут еще раз про проблему эту спрашивать, я сюда буду отправлять.

О чем Вы вообще, разберитесь в материале, понимаете где проблема возникает и почему? Нету никакого топика error на момент старта wb-rules.

Здравствуйте. Расскажите, пожалуйста, глубже, в чём проблема? В скриптах используются своеобразные подписки на топики, вроде when/whenchanged и они не выполнятся, если топиков не будет. То есть на первый взгляд кажется, что нет топиков => не выполняется код правил.

То есть я вот эту часть проблемы не могу понять, если руководствоваться тезисом выше. В коде есть некая функция, которая при старте получает список топиков и создаёт в HA устройства разом?

В контексте моего скрипта, который используют для добавления устройств из WB в HomeAssistant, алгоритм следующий: на старте запускается python скрипт, который получает все доступные на момент старта топики, из которых строит список устройств и публикует их для HomeAssistant. И у пользователей проблема, что на момент запуска wb-rules устройства в MQTT отсутствуют , соответственно публиковать потом нечего. Как “решение” я предлагаю использовать механизм persistence в mosquitto, но не всем это может подходить.

Про wb-rules не понял, у вас же python скрипт. Или это две разные проблемы в разных местах?

Мы просто пытаемся понять проблему.

Скрипт состоит из нескольких частей. Основная часть работает как модуль wb-rules: запускается при его старте, читает конфигурацию, создаёт виртуальные устройства типа «термостат», обслуживает их логику и запускает Python-скрипт, который читает топики MQTT и публикует устройства в Home Assistant. Также есть шаблон для jsonEditor’а (формируется с помощью Python-скрипта), который используется для отображения формы настроек в интерфейсе Wiren Board. При применении настроек он перезапускает wb-rules.

Идея была простой: не пытаться создавать парсер конфигурации, а сделать парсер устройств в соответствии с MQTT Conventions. Таким образом, скрипт может пробрасывать любые устройства, присутствующие в MQTT.

Кстати, о MQTT Conventions: пока вспомнил, почему у устройств WB-MSW поменяли type = temperature на type = value? Мне кажется, наоборот, логичнее уходить от «безликого» type = value и вводить понятные категории для разных параметров. Тем более что у разных шаблонов MSW это реализовано по-разному: где-то оставили temperature, а где-то заменили на value (вот тут смотрю). Были жалобы, что перестало правильно работать — оказалось, скрипт перестал понимать, какого типа значение. Пришлось явно прописать для MSW типы по названиям топиков.

1 лайк

Вот типичный пример, где это не работает.
У меня есть zigbee датчик. Он публикует значения довольно редко. Скрипт wb-rules, который использует его, датчика, значения подписявается на топик датчика (кроме прочих). Ну и создает виртуальное устройство. Скрипт, естественно отрабатывает при запуске, подписывается, Пока топика нет (датчик еще ничего не публиковал) - подписка все равно активна. И даже если топика еще не существует. Топик появился - значения опубликовались - подписка стработала.
Точно так же этот датчик описан в HA, топиком. Никаких проблем не возникает с отсутствием топика, ничего не ломается.

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

1 лайк

Здравствуйте. Разработчики сказали, что добавлять статус в один сервис не будут, а добавлять во все (ведь в контроллере не только Modbus-устройства), оно потом обрастёт зависимостями и кучей мест, где может сломаться.

Идеология wb-rules — событийная. То есть произошло событие — отреагировали. Так и с топиками.

Поэтому, я вижу два решения:

  1. Верное — сделать так, чтобы ваш скрипт мог обрабатывать динамически созданные топики.
  2. Неверное и не надёжное, так как в будущих версиях поведение может измениться — следить за топиком /rpc/v1/wb-mqtt-serial/config/Load. Как только там появилась 1 — драйвер загрузился.

Я попробую ещё раз поговорить с разработчиками и описать вашу проблему, но это без гарантий.

2 лайка

Я как раз понимаю. Да, гораздо удобнее когда все окружение статично и не меняется.

Это совсем не абстрактный пример. Как раз именно работающий, вот прямо сейчас. И значение виртуального устройства - передается в HA.
Когдда проектирую - стараюсь чтобы перезапуск или временное отключение любого сервиса не влияло нна работу остальных.