Перейти к содержанию

Как внести изменения

Перед тем как править блюпринт

Вся логика живёт в блоке variables: и шаблонных триггерах. Блок actions: намеренно оставлен тонким: он только исполняет уже принятые решения. Держитесь этого разделения — оно и делает блюпринт тестируемым.

Обязательные требования к правкам

  1. Тесты должны проходить. pytest — полный прогон около десяти минут, основная часть времени уходит на мутационное тестирование.
  2. Новая переменная — новый тест. Как минимум нормальный случай и границы.
  3. Порядок объявления переменных имеет значение. Home Assistant рендерит variables: сверху вниз; ссылка на переменную, объявленную ниже, молча даст пустое значение. За этим следит test_variables_are_defined_before_they_are_used.
  4. Каждый вызов службы — с continue_on_error: true. Отвалившаяся облачная интеграция не должна прерывать последовательность на середине.
  5. Никаких блокирующих delay перед командами. Автоматизация работает в режиме restart: любое срабатывание триггера обрывает незавершённую паузу вместе со всем, что шло после неё. Если нужно выдержать интервал — делайте это проверкой (как gap_elapsed), чтобы команда просто откладывалась до следующего пересчёта. Тесты этого не поймают: они рендерят variables:, а не исполняют actions: с таймингом.
  6. Новый вход — обязательно с описанием. Блюпринт рассчитан на людей, которые видят его впервые и не знают внутренней терминологии.
  7. Никаких названий конкретных марок в описаниях. Примеры имён сущностей допустимы, но как «в интеграциях обычно называется так».

Если понадобилась новая функция шаблонов

Добавьте её в tests/ha_sim.py, в _build_helpers. Движок реализует только то подмножество API Home Assistant, которое реально используется. Это осознанное ограничение: оно не даёт тестам молча пропустить опечатку в имени функции.

Реализуйте её строго как в Home Assistant, включая отказы. Движок, который мягче настоящего HA, страшнее отсутствующего: тесты зеленеют, а в проде ломается. Например, is_number в HA отвергает inf и nan, а states[''] бросает исключение вместо того, чтобы вернуть None.

Мутационное тестирование

Если вы добавляете значимое поведение, добавьте и мутацию в tests/test_mutations.py: фрагмент шаблона и его сломанную версию. Так проверяется, что новый тест действительно что-то ловит, а не просто зеленеет.

Если правка меняет текст шаблона, на который ссылается существующая мутация, тест упадёт с понятным сообщением «mutation no longer matches the blueprint» — обновите фрагмент.

Проверки перед отправкой

pytest -m "not slow"
pytest -m slow -n auto
ruff check tests/ tools/
yamllint -c .yamllint.yaml blueprints/ .github/ .yamllint.yaml

Если правили секцию input: — прогоните ещё и проверку настоящим Home Assistant. Она единственная знает, какие ключи допустимы в селекторах:

pip install homeassistant && python tests/validate_with_home_assistant.py

Если правили tests/ha_sim.py — прогоните сверку движка с настоящим Home Assistant. Набор целиком работает на этом эмуляторе и потому не может заметить, что тот разошёлся с оригиналом:

pip install homeassistant && python tests/differential_against_home_assistant.py

Добавили в движок новую функцию — добавьте её вызовы и в список шаблонов этого скрипта, иначе у новой реализации не будет эталона.

Если правили tools/trace_report.py — он намеренно держит совместимость с Python 3.9 и не требует ни одного стороннего пакета. Люди запускают его системным интерпретатором, чтобы приложить вывод к баг-репорту, и просить их сначала поставить окружение — значит не получить отчёт вовсе. Основной ruff настроен на 3.11 и такую несовместимость не поймает, поэтому проверяйте отдельно:

ruff check --target-version py39 tools/ && /usr/bin/python3 -m py_compile tools/trace_report.py

Изменения, ломающие совместимость

Переименование или удаление входа сбрасывает настройку у всех, кто уже пользуется блюпринтом. Если без этого никак — поднимите мажорную версию в CHANGELOG.md и в строке версии внутри описания блюпринта, и опишите в changelog, что именно нужно перенастроить.


Где лежит исходник

Эта страница собирается из CONTRIBUTING.md в корне репозитория — правки вносите туда.