Contributing to Homematic(IP) Local for OpenCCU

March 6, 2026 · View on GitHub

Thank you for your interest in contributing to the Homematic(IP) Local integration! This document provides guidelines for contributing to the project.

Table of Contents


Code of Conduct

This project follows the Contributor Covenant 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 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

If you use VS Code with the DevContainer extension:

# Open the project in VS Code
# Accept the prompt to reopen in DevContainer
# Environment will be automatically configured

Option 2: Manual Setup

# Clone the repository
git clone https://github.com/sukramj/homematicip_local.git
cd homematicip_local

# Create virtual environment
python3.14 -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements_test.txt

# Or use uv (faster)
uv pip install -r requirements_test.txt

# Setup prek hooks
prek install

Verify Installation

# Run tests
pytest tests/

# Run code quality checks
prek run --all-files

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.

# ✅ 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:

from __future__ import annotations

Import Order

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

# 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
# ✅ 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:

prek run --all-files

Do NOT bypass hooks with --no-verify unless absolutely necessary.


Testing

All code changes must include tests.

Running Tests

# Run all tests with coverage
pytest --cov=custom_components tests

# Run specific test file
pytest tests/test_config_flow.py

# Run with verbose output
pytest -v tests/

# Generate HTML coverage report
pytest --cov=custom_components --cov-report=html tests/
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

  • master: Stable release branch (protected)
  • devel: Development 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 devel:

    git checkout devel
    git pull origin devel
    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:

    # Run tests
    pytest --cov=custom_components tests
    
    # Run prek hooks
    prek run --all-files
    
  5. Commit your changes:

    git add .
    git commit -m "feat: Add support for new device type"
    
  6. Push to your fork/branch:

    git push -u origin feature/my-feature
    
  7. Create a Pull Request to the devel branch

Commit Message Format

Follow Conventional Commits:

<type>(<scope>): <subject>

<body>

<footer>

Types: feat, fix, docs, style, refactor, test, chore

Examples:

feat(climate): Add boost mode support for HmIP-eTRV-2

Implements boost mode functionality with new service
and entity attributes for thermostat devices.

Closes #123
fix(config_flow): Handle connection timeout gracefully

Added retry logic with exponential backoff for CCU
connection validation during config flow.

Pull Request Guidelines

  • Title: Clear, descriptive title
  • Description: Explain what and why (not how)
  • Link issues: Reference related issues with Closes #123
  • Target branch: Always target devel, not master
  • Pass CI checks: All automated checks must pass
  • Code review: Be responsive to feedback

What Happens Next

  1. Automated CI checks run (tests, linting, type checking)
  2. Code review by maintainers
  3. Discussion and iteration if changes are needed
  4. Merge to devel once approved
  5. Release to master in next version

Reporting Issues

Before Opening an Issue

  1. Search existing issues: Your issue may already be reported
  2. Check discussions: Feature requests often start as discussions
  3. Gather information: Logs, Home Assistant version, device details

Opening an Issue

Use the appropriate issue template:

  • Bug Report: Describe the bug with reproduction steps
  • Feature Request: Describe the feature and use case
  • Question: Ask for help or clarification

Include:

  • Home Assistant version
  • Integration version
  • CCU/hub type and version
  • Device model (if device-specific)
  • Relevant logs (enable debug logging if needed)

Debug Logging

Enable debug logging in configuration.yaml:

logger:
  default: info
  logs:
    custom_components.homematicip_local: debug
    aiohomematic: debug

Additional Resources

Documentation

Getting Help

  • GitHub Discussions: For questions and feature discussions
  • GitHub Issues: For bug reports

Quick Reference

Common Commands

# Format code
ruff format custom_components/homematicip_local/

# Lint code
ruff check --fix custom_components/homematicip_local/

# Type check
mypy custom_components/homematicip_local/

# Run all quality checks
prek run --all-files

# Run tests
pytest --cov=custom_components tests

# Check translations
python script/check_translations.py

Key Files

FilePurpose
custom_components/homematicip_local/__init__.pyIntegration entry point
custom_components/homematicip_local/config_flow.pyConfiguration UI
custom_components/homematicip_local/control_unit.pyCentral control logic
custom_components/homematicip_local/services.pyService handlers
custom_components/homematicip_local/const.pyConstants and enums
custom_components/homematicip_local/manifest.jsonIntegration metadata
custom_components/homematicip_local/strings.jsonUI translations

Thank you for contributing to Homematic(IP) Local! 🎉

Your contributions help make this integration better for everyone in the Home Assistant community.