7.4 KiB
Copilot Instructions
This repository contains a custom component for Home Assistant, intended to be distributed via the HACS (Home Assistant Community Store).
Development Guidelines
-
Follow the official Home Assistant development guidelines at developers.home-assistant.io.
-
Ensure compatibility with the latest Home Assistant release.
-
Use async functions, non-blocking I/O, and config flows where applicable.
-
Structure the component using these standard files:
__init__.py– setup and teardownmanifest.json– metadata and dependenciesconfig_flow.py– if the integration supports UI configurationsensor.py,switch.py, etc. – for platformsconst.py– constants (DOMAIN,CONF_*, etc.)
-
Use Home Assistant's built-in helpers and utility modules:
homeassistant.helpers.entity,device_registry,config_validationhomeassistant.util.dt(dt_util) for time/date handling
-
Do not wrap built-in functions (e.g., don’t wrap
dt_util.parse_datetime) -
Avoid third-party or custom libraries unless absolutely necessary
-
Never assume static local file paths — use config options and relative paths
Coding Style
- Follow PEP8, enforced by Black, isort, and Ruff
- Use type hints on all function and method signatures
- Add docstrings for all public classes and methods
- Use f-strings for string formatting
- Do not use
print()— use_LOGGERfor logging - YAML examples must be valid, minimal, and Home Assistant compliant
Code Structure and Ordering
Use the following order inside Python modules:
-
Imports
- Python standard library imports first
- Third-party imports (e.g.,
homeassistant.*) - Local imports within this component (
from . import xyz) - Enforced automatically by
isort
-
Module-level constants and globals
- Define constants and globals at module-level (e.g.,
DOMAIN,_LOGGER,CONF_*,DEFAULT_*)
- Define constants and globals at module-level (e.g.,
-
Top-level functions
- Use only for stateless, reusable logic
- Prefix with
_if internal only (e.g.,_parse_price()) - Do not place Home Assistant lifecycle logic here
- Sort and group top-level functions for maximum readability:
- Place public API/entry point functions (e.g., service handlers, async setup) at the top of the function section.
- Direct helpers (called by entry points) immediately after, in the order they are called.
- Pure/stateless utility functions that are not tightly coupled to entry points at the end.
- Where possible, order functions so that a function appears before any function that calls it (call hierarchy order).
- Group related functions by logical purpose or data handled, and use
#region/#endregionfolding comments for large files if needed.
-
Main classes
- Define main classes (Home Assistant Entity classes, DataUpdateCoordinators, and ConfigFlow handlers)
- Order inside class:
- Special methods (
__init__,__repr__) - Public methods (no
_) - Private methods (
_prefix)
- Special methods (
- All I/O or lifecycle methods must be
async def
-
Helper classes
- If helper classes become complex, move them to separate modules (e.g.,
helpers.py,models.py)
- If helper classes become complex, move them to separate modules (e.g.,
✅ Copilot tip:
- Use top-level functions for pure helpers only.
- Prefer structured classes where Home Assistant expects them.
- Sort and group functions for maximum readability and maintainability, following call flow from entry points to helpers to utilities.
Code Comments Policy
- Do not add comments in the code to explain automated changes, such as reordering, renaming, or compliance with coding standards or prompts.
- Comments in code should be reserved only for documenting the actual logic, purpose, or usage of code elements (e.g., classes, methods, functions, or complex logic blocks).
- If any explanations of automated actions are needed, provide them outside the code file (such as in your chat response, PR description, or commit message), not within the Python files themselves.
- Do not insert comments like
# moved function,# renamed,# for compliance, or similar into code files.
Backwards Compatibility Policy
- Do not implement or suggest backward compatibility features, workarounds, deprecated function support, or compatibility layers unless explicitly requested in the prompt or project documentation.
- All code should assume a clean, modern codebase and should target the latest stable Home Assistant version only, unless otherwise specified.
- If you believe backward compatibility might be required, ask for clarification first before adding any related code.
Data Structures
Use @dataclass for plain data containers where appropriate:
from dataclasses import dataclass
@dataclass
class PriceSlot:
start: datetime
end: datetime
price: float
Visual File Layout
Split component logic into multiple Python modules for improved clarity and maintainability:
/custom_components/your_component/
├── __init__.py
├── manifest.json
├── const.py
├── sensor.py
├── config_flow.py
├── models.py # dataclasses
├── helpers.py # pure utility functions
Use #region / #endregion optionally to improve readability in large files.
Optional Files (Custom Integration via HACS)
Only create these files if explicitly required by your integration features. Not all files used in Core integrations apply to Custom Integrations:
services.yaml– Define custom Home Assistant servicestranslations/*.json(e.g.,en.json,de.json) – Provide translations for UI elements- Additional platform files (e.g.,
binary_sensor.py,switch.py,number.py,button.py,select.py) – Support for additional entity types websocket_api.py– Define custom WebSocket API endpointsdiagnostics.py– Provide diagnostic data to users and maintainersrepair.py– Offer built-in repair hints or troubleshooting guidanceissue_registry.py– Communicate integration-specific issues or important changes to users clearly
⚠️ Copilot tip: Avoid Core-only files (
device_action.py,device_trigger.py,device_condition.py,strings.json) for Custom Integrations. These are typically not supported or rarely used.
Linting and Code Quality
-
Enforced by Ruff, which runs:
- Locally via VS Code devcontainer
- Remotely via GitHub Actions
Key Ruff linter rules that must be followed:
F401,F841– No unused imports or variablesE402,E501– Imports at top, lines ≤88 charsC901,PLR0912,PLR0915– Functions must be small and simplePLR0911,RET504– No redundantelseafterreturnB008– No mutable default argumentsT201– Do not useprint()SIM102– Preferif xoverif x == True
Also:
- Use Black for formatting
- Use isort for import sorting
- See
.ruff.tomlfor custom settings - Prefer one return statement per function unless early returns improve clarity
Tests
This integration does not include automated tests by default.
⚠️ If Copilot generates tests, keep them minimal and do not introduce new test frameworks not already present.