# Contributing to Homematic(IP) Local for OpenCCU Thank you for your interest in contributing to the Homematic(IP) Local integration! This document provides guidelines for contributing to the project. > **Note on AI tools:** AI-assisted contributions are welcome, but fully autonomous agent > submissions (unreviewed AI-generated pull requests or issues) are not accepted. See > [AI_POLICY.md](AI_POLICY.md) for the full AI contribution policy. ## Table of Contents - [Code of Conduct](#code-of-conduct) - [Getting Started](#getting-started) - [Development Environment Setup](#development-environment-setup) - [Code Quality Standards](#code-quality-standards) - [Testing](#testing) - [Submitting Changes](#submitting-changes) - [Reporting Issues](#reporting-issues) - [Additional Resources](#additional-resources) --- ## Code of Conduct This project follows the [Contributor Covenant Code of Conduct](https://www.contributor-covenant.org/version/2/1/code_of_conduct/). By participating, you are expected to uphold this code. --- ## Getting Started ### Ways to Contribute - **Report bugs**: Open an issue with detailed information - **Suggest features**: Discuss ideas in GitHub Discussions - **Improve documentation**: Fix typos, clarify instructions, add examples - **Submit code**: Fix bugs or implement new features via Pull Requests ### Before You Start 1. **Check existing issues**: Search for similar issues or feature requests 2. **Discuss major changes**: For significant features, open a discussion first 3. **Review the architecture**: Read [CLAUDE.md](CLAUDE.md) for technical details --- ## Development Environment Setup ### Prerequisites - **Python 3.14+** (required for development) - **Git** for version control - **pip** or **uv** (recommended) for package management ### Quick Setup #### Option 1: DevContainer (Recommended) If you use VS Code with the DevContainer extension: ```bash # Open the project in VS Code # Accept the prompt to reopen in DevContainer # Environment will be automatically configured ``` #### Option 2: Manual Setup ```bash # Clone the repository git clone https://github.com/sukramj/homematicip_local.git cd homematicip_local # Create virtual environment (./venv, Python 3.14) make venv # Install dependencies and prek hooks make setup ``` ### Verify Installation ```bash # Run tests make test # Run code quality checks make prek ``` ### The Makefile All development tasks run through the `Makefile` — `make help` lists every target, grouped by topic (setup, code quality, tests, validation, run, housekeeping). Targets activate `./venv` automatically (via `script/run-in-env.sh`), so they work whether or not your virtual environment is activated. --- ## Code Quality Standards This project maintains high code quality standards. All contributions must pass automated checks. ### Type Annotations (mypy - STRICT MODE) **All code must be fully typed.** This project uses mypy in strict mode. ```python # ✅ CORRECT def get_device(self, *, address: str) -> Device | None: """Return device by address.""" return self._devices.get(address) # ❌ INCORRECT - Missing type annotations def get_device(self, address): return self._devices.get(address) ``` ### Import Requirements **Every Python file must start with:** ```python from __future__ import annotations ``` #### Import Order ```python from __future__ import annotations # 1. Standard library import asyncio from typing import TYPE_CHECKING # 2. Third-party (Home Assistant) from homeassistant.core import HomeAssistant # 3. First-party (aiohomematic) from aiohomematic.const import Interface # 4. Local imports from .const import DOMAIN # 5. TYPE_CHECKING imports (to avoid circular imports) if TYPE_CHECKING: from aiohomematic.central import CentralUnit ``` ### Code Style ```python # Use keyword-only arguments for all parameters (except self/cls) def create_entity( *, # Force keyword-only control_unit: ControlUnit, data_point: DataPoint, ) -> Entity: """Create a new entity.""" ... # Docstrings required for all public classes and methods class HmDevice: """Representation of a Homematic device.""" def get_channel(self, *, channel_no: int) -> Channel | None: """Return channel by number.""" ... ``` ### Docstring Standards - **Always end with a period (`.`)** - **Use imperative mood** for methods: "Return the device" (not "Returns" or "Gets") - **Use declarative statements** for classes: "Represents a device" - **Keep them concise**: Rely on type hints instead of repeating type information ```python # ✅ CORRECT @property def device_address(self) -> str: """Return the device address.""" # ❌ INCORRECT - No period, wrong verb tense @property def device_address(self) -> str: """Returns the address as a string""" ``` ### Prek Hooks Prek hooks run automatically on every commit. They enforce: - Code formatting (ruff) - Type checking (mypy) - Linting (ruff, pylint) - Spell checking (codespell) - YAML validation (yamllint) - Translation validation **Run manually:** ```bash make prek ``` **Do NOT bypass** hooks with `--no-verify` unless absolutely necessary. --- ## Testing All code changes must include tests. ### Running Tests ```bash # Run all tests make test # Run all tests with coverage make test-cov # Run specific test file make test-file FILE=tests/test_config_flow.py # Pass extra pytest arguments make test PYTEST_ARGS="-x -vv" # Generate HTML coverage report make test-cov-html open htmlcov/index.html ``` ### Test Requirements - **New features**: Must include tests for all new functionality - **Bug fixes**: Must include regression test - **Coverage**: Aim for 100% coverage on modified files - **All tests must pass** before submitting PR ### Test Framework - **pytest** with pytest-homeassistant-custom-component - **Asyncio mode**: Tests use `@pytest.mark.asyncio` - **Fixtures**: Use existing fixtures from `tests/conftest.py` --- ## Submitting Changes ### Branch Structure - **`main`**: Default branch (protected) - **Feature branches**: `feature/description` or `fix/description` ### Workflow 1. **Fork the repository** (external contributors) or create a branch (maintainers) 2. **Create a feature branch** from `main`: ```bash git checkout main git pull origin main git checkout -b feature/my-feature ``` 3. **Make your changes**: - Write code following the standards above - Add tests for all changes - Update documentation if needed 4. **Run quality checks**: ```bash # Run prek hooks and tests with coverage make check ``` 5. **Commit your changes**: ```bash git add . git commit -m "feat: Add support for new device type" ``` 6. **Push to your fork/branch**: ```bash git push -u origin feature/my-feature ``` 7. **Create a Pull Request** to the `main` branch ### Commit Message Format Follow [Conventional Commits](https://www.conventionalcommits.org/): ``` ():