Столкнулись с проблемой, сейчас 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 её в качестве зависимостей для запуска.
Добрый день.
Если выбранное решение вас устраивает - то хорошо.
Но, позволю себе пару замечаний.
Первое: а по какому признаку считать что 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? Дальше уже пользователи сами смогут решить, ставить ли эту службу в зависимость или нет.
Не “из-за этого”. Проблема в том, что устройство, опрашиваемое wb-rules, недоступно. И только в этом. А причины этого: помехи на шине, физически отвалилось … не запущен wb-mqtt-serial … их много.
Имхо, скрипты, чувствительные к результату, обязаны использовать топик error
То есть только вот это использовать.В самом скрипте учитывать доступность.
Иначе, … например, в момент срабатывания правила устройство недоступно (красное) или недоступен зависимый топик … в этом случае будет ошибка wb-rules
Использование топика error делает правило отказоустойчивый" по любым причинам.
И плохо, что это не рассмотрено в примерах правил в документации, наверное.
Поэтому, “наверное” …
Да и, основная документация не в справке, а там все нормально расписано.
Но обычно все начинается с copy/paste, править под себя и … не учитываются важные моменты (тот же error, некоторые стартовые моменты …). Особенно “начинающими”.
Ну, я всегда, когда что-то пишу перед тем как ту же функцию писать думаю: а что если на вход вместо ожидаемого float придет указатель на строковый массив? А если null? Offtop: ошибка в типах - это вообще классика, особенно в скриптах, в которых автоприведение часто работает как надо. А редко, но больно - как покажется интерпретатору правильным.
Предполагается что начинает писать имеющий какой-то опыт разработчик, кому надо подробно рассказать про особенности работы с объектами.
Вот тут согласен. (И вообще многих языков программирования касается - везде есть особенности.
Но в случае с автоматизацией дома, это еще и … безопасность.
И тут очень много факторов.
Это далеко не так. А некоторые вопросы, не только тут на форуме, … прямо хочется вместо ответа послать сначала изучить теорию или к разработчику (вы к интеграторам посылаете).
Все там хорошо написано.
Но, имхо, все примеры кода с конкретной логикой все равно должны быть максимально “безопасными”, обернутыми в максимальное число проверок (даже если это не очень нужно) … чтобы “начинающий” понял как “правильно”, и потом уже на свой страх и риск переделал и максимально упростил.
Но это все имхо (личное мнение), написание документации отнимает не мало времени …
Здравствуйте. Расскажите, пожалуйста, глубже, в чём проблема? В скриптах используются своеобразные подписки на топики, вроде when/whenchanged и они не выполнятся, если топиков не будет. То есть на первый взгляд кажется, что нет топиков => не выполняется код правил.
То есть я вот эту часть проблемы не могу понять, если руководствоваться тезисом выше. В коде есть некая функция, которая при старте получает список топиков и создаёт в HA устройства разом?
В контексте моего скрипта, который используют для добавления устройств из WB в HomeAssistant, алгоритм следующий: на старте запускается python скрипт, который получает все доступные на момент старта топики, из которых строит список устройств и публикует их для HomeAssistant. И у пользователей проблема, что на момент запуска wb-rules устройства в MQTT отсутствуют , соответственно публиковать потом нечего. Как “решение” я предлагаю использовать механизм persistence в mosquitto, но не всем это может подходить.
Скрипт состоит из нескольких частей. Основная часть работает как модуль 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 типы по названиям топиков.
Вот типичный пример, где это не работает.
У меня есть zigbee датчик. Он публикует значения довольно редко. Скрипт wb-rules, который использует его, датчика, значения подписявается на топик датчика (кроме прочих). Ну и создает виртуальное устройство. Скрипт, естественно отрабатывает при запуске, подписывается, Пока топика нет (датчик еще ничего не публиковал) - подписка все равно активна. И даже если топика еще не существует. Топик появился - значения опубликовались - подписка стработала.
Точно так же этот датчик описан в HA, топиком. Никаких проблем не возникает с отсутствием топика, ничего не ломается.
Ничего личного, но Вы не пытаетесь понять логику работы и почему оно не работает и о чем я пишу, зачем эти все абстрактные примеры мне не понятно, есть конкретная причина почему не работает, есть пути как это решить. Если Вы не хотите разобраться и понять что и как , можете закрыть этот тред и все, я уговаривать не хочу.
Здравствуйте. Разработчики сказали, что добавлять статус в один сервис не будут, а добавлять во все (ведь в контроллере не только Modbus-устройства), оно потом обрастёт зависимостями и кучей мест, где может сломаться.
Идеология wb-rules — событийная. То есть произошло событие — отреагировали. Так и с топиками.
Поэтому, я вижу два решения:
Верное — сделать так, чтобы ваш скрипт мог обрабатывать динамически созданные топики.
Неверное и не надёжное, так как в будущих версиях поведение может измениться — следить за топиком /rpc/v1/wb-mqtt-serial/config/Load. Как только там появилась 1 — драйвер загрузился.
Я попробую ещё раз поговорить с разработчиками и описать вашу проблему, но это без гарантий.
Я как раз понимаю. Да, гораздо удобнее когда все окружение статично и не меняется.
Это совсем не абстрактный пример. Как раз именно работающий, вот прямо сейчас. И значение виртуального устройства - передается в HA.
Когдда проектирую - стараюсь чтобы перезапуск или временное отключение любого сервиса не влияло нна работу остальных.