hass.tibber_prices/docs/developer/docs/coding-guidelines.md
Julian Pawlowski d73eda4b2f git commit -m "feat(docs): add dual Docusaurus sites with custom branding and Giscus integration
- Split documentation into separate User and Developer sites
- Migrated existing docs to proper Docusaurus structure
- Added custom Tibber-themed header logos (light + dark mode variants)
- Implemented custom color scheme matching integration branding
  - Hero gradient: Cyan → Dark Cyan → Gold
  - Removed standard Docusaurus purple/green theme
- Integrated Giscus comments system for community collaboration
  - User docs: Comments enabled on guides, examples, FAQ
  - User docs: Comments disabled on reference pages (glossary, sensors, troubleshooting)
  - Developer docs: No comments (GitHub Issues/PRs preferred)
- Added categorized sidebars with emoji navigation
- Created 8 new placeholder documentation pages
- Fixed image paths for baseUrl compatibility (local + GitHub Pages)
- Escaped MDX special characters in performance metrics
- Added GitHub Actions workflow for automated deployment
- Created helper scripts: dev-user, dev-developer, build-all

Breaking changes:
- Moved /docs/user/*.md to /docs/user/docs/*.md
- Moved /docs/development/*.md to /docs/developer/docs/*.md
2025-12-06 01:37:06 +00:00

3 KiB

comments
false

Coding Guidelines

Note: For complete coding standards, see AGENTS.md.

Code Style

  • Formatter/Linter: Ruff (replaces Black, Flake8, isort)
  • Max line length: 120 characters
  • Max complexity: 25 (McCabe)
  • Target: Python 3.13

Run before committing:

./scripts/lint        # Auto-fix issues
./scripts/release/hassfest    # Validate integration structure

Naming Conventions

Class Names

All public classes MUST use the integration name as prefix.

This is a Home Assistant standard to avoid naming conflicts between integrations.

# ✅ CORRECT
class TibberPricesApiClient:
class TibberPricesDataUpdateCoordinator:
class TibberPricesSensor:

# ❌ WRONG - Missing prefix
class ApiClient:
class DataFetcher:
class TimeService:

When prefix is required:

  • Public classes used across multiple modules
  • All exception classes
  • All coordinator and entity classes
  • Data classes (dataclasses, NamedTuples) used as public APIs

When prefix can be omitted:

  • Private helper classes within a single module (prefix with _ underscore)
  • Type aliases and callbacks (e.g., TimeServiceCallback)
  • Small internal NamedTuples for function returns

Private Classes:

If a helper class is ONLY used within a single module file, prefix it with underscore:

# ✅ Private class - used only in this file
class _InternalHelper:
    """Helper used only within this module."""
    pass

# ❌ Wrong - no prefix but used across modules
class DataFetcher:  # Should be TibberPricesDataFetcher
    pass

Note: Currently (Nov 2025), this project has NO private classes - all classes are used across module boundaries.

Current Technical Debt:

Many existing classes lack the TibberPrices prefix. Before refactoring:

  1. Document the plan in /planning/class-naming-refactoring.md
  2. Use multi_replace_string_in_file for bulk renames
  3. Test thoroughly after each module

See AGENTS.md for complete list of classes needing rename.

Import Order

  1. Python stdlib (specific types only)
  2. Third-party (homeassistant.*, aiohttp)
  3. Local (.api, .const)

Critical Patterns

Time Handling

Always use dt_util from homeassistant.util:

from homeassistant.util import dt as dt_util

price_time = dt_util.parse_datetime(starts_at)
price_time = dt_util.as_local(price_time)  # Convert to HA timezone
now = dt_util.now()

Translation Loading

# In __init__.py async_setup_entry:
await async_load_translations(hass, "en")
await async_load_standard_translations(hass, "en")

Price Data Enrichment

Always enrich raw API data:

from .price_utils import enrich_price_info_with_differences

enriched = enrich_price_info_with_differences(
    price_info_data,
    thresholds,
)

See AGENTS.md for complete guidelines.