mirror of
https://github.com/jpawlowski/hass.tibber_prices.git
synced 2026-03-30 13:23:41 +00:00
178 lines
6.5 KiB
Markdown
178 lines
6.5 KiB
Markdown
# Copilot Instructions
|
||
|
||
This repository contains a **Home Assistant custom integration** providing Tibber electricity price information and ratings, distributed via **HACS**.
|
||
|
||
## Repository Overview
|
||
|
||
- **Type**: Home Assistant Custom Integration (~5,100 lines Python)
|
||
- **Language**: Python 3.13, async/await
|
||
- **Framework**: Home Assistant 2025.10.0+
|
||
- **Main Components**: Sensors, Binary Sensors, Services, Config Flow, Data Coordinator
|
||
- **Testing**: pytest with pytest-homeassistant-custom-component (7 test files)
|
||
|
||
## Build, Lint, and Test Commands
|
||
|
||
### Setup (ALWAYS Run First)
|
||
|
||
```bash
|
||
scripts/setup # Installs dependencies
|
||
```
|
||
|
||
**Note**: `homeassistant>=2025.10.0` may not be in PyPI. Use devcontainer for full environment.
|
||
|
||
### Linting (ALWAYS Run Before Commit)
|
||
|
||
```bash
|
||
scripts/lint # Runs: ruff format . && ruff check . --fix
|
||
```
|
||
|
||
- CI enforces via `.github/workflows/lint.yml` (runs `ruff format --check` and `ruff check`)
|
||
- **CI will fail if linting errors exist**
|
||
- Key rules: F401, F841, E402, E501, C901, PLR0912/15/11, RET504, B008, T201, SIM102
|
||
- Line length: 120 chars (see `.ruff.toml`)
|
||
|
||
### Testing
|
||
|
||
```bash
|
||
pytest tests/ # Run all tests
|
||
pytest tests/test_price_utils.py # Run specific test
|
||
```
|
||
|
||
Tests in `tests/` directory cover price utilities, coordinator, midnight turnover, services.
|
||
|
||
### CI Validation
|
||
|
||
Two workflows run on push/PR:
|
||
|
||
1. **`validate.yml`**: hassfest (HA manifest validation) + HACS validation
|
||
2. **`lint.yml`**: Ruff format + lint checks
|
||
|
||
**Replicate CI locally**: Run `scripts/lint` – if it passes, CI will pass.
|
||
|
||
### Development Environment
|
||
|
||
Use VS Code devcontainer (`.devcontainer/devcontainer.json`):
|
||
|
||
- Python 3.13, auto-runs `scripts/setup`
|
||
- Home Assistant on port 8123
|
||
- Start: `scripts/develop` (runs `hass --config ./config --debug`)
|
||
|
||
## Development Guidelines
|
||
|
||
- Follow [developers.home-assistant.io](https://developers.home-assistant.io)
|
||
- Use async functions, non-blocking I/O, config flows
|
||
- Standard files: `__init__.py`, `manifest.json`, `config_flow.py`, `sensor.py`, `const.py`
|
||
- Use HA helpers: `homeassistant.helpers.entity`, `device_registry`, `dt_util`
|
||
- Don't wrap built-ins, avoid third-party libs, no static file paths
|
||
|
||
## Coding Style
|
||
|
||
- **PEP8** via Black, isort, Ruff
|
||
- Type hints + docstrings on all public methods
|
||
- F-strings for formatting
|
||
- Use `_LOGGER`, not `print()`
|
||
|
||
### Module Structure Order
|
||
|
||
1. Imports (stdlib → third-party → local)
|
||
2. Module constants/globals
|
||
3. Top-level functions (public → helpers → utilities)
|
||
4. Main classes (Entity, Coordinator, ConfigFlow)
|
||
5. Helper classes (or move to separate modules)
|
||
|
||
### Code Comments Policy
|
||
|
||
- **No** comments for automated changes (reordering, renaming, compliance)
|
||
- Comments **only** for logic/purpose/usage
|
||
- Explanations go in PR/commit messages, not code
|
||
|
||
## Backwards Compatibility Policy
|
||
|
||
- **Do not** add compatibility layers unless explicitly requested
|
||
- Target latest stable HA version only
|
||
|
||
## Translations Policy
|
||
|
||
- User-facing strings in `translations/en.json` and other `translations/*.json`
|
||
- **All translation files must sync** – update all languages when adding/changing keys
|
||
- `custom_translations/` for supplemental strings not in standard HA format
|
||
- Never duplicate keys between `translations/` and `custom_translations/`
|
||
- Standard translations take priority over custom
|
||
|
||
## Project Layout
|
||
|
||
```
|
||
/
|
||
├── .github/workflows/ # CI: lint.yml, validate.yml
|
||
├── .devcontainer/ # VS Code dev container
|
||
├── custom_components/tibber_prices/ # Main code (5,100 lines)
|
||
│ ├── __init__.py (115) # Entry point
|
||
│ ├── const.py (473) # Constants
|
||
│ ├── api.py (850) # Tibber API client
|
||
│ ├── coordinator.py (536) # Data coordinator
|
||
│ ├── sensor.py (859) # Sensor platform
|
||
│ ├── binary_sensor.py (693) # Binary sensors
|
||
│ ├── config_flow.py (494) # UI config
|
||
│ ├── services.py (639) # Custom services
|
||
│ ├── price_utils.py (291) # Price calculations
|
||
│ ├── services.yaml # Service definitions
|
||
│ ├── translations/ # Standard HA translations (en, de)
|
||
│ └── custom_translations/ # Supplemental translations
|
||
├── config/configuration.yaml # Dev HA config
|
||
├── scripts/
|
||
│ ├── setup # Install deps
|
||
│ ├── lint # Ruff format & check
|
||
│ └── develop # Start HA
|
||
├── tests/ # pytest suite (7 files)
|
||
├── .ruff.toml # Linting config
|
||
├── pyproject.toml # Black/isort config
|
||
├── requirements.txt # Dependencies
|
||
└── hacs.json # HACS metadata
|
||
```
|
||
|
||
### Configuration Files
|
||
|
||
- **`.ruff.toml`**: Python 3.13, line length 120, ALL rules with selective ignores
|
||
- **`pyproject.toml`**: Black/isort (line length 120)
|
||
- **`.editorconfig`**: 4-space indent, LF, UTF-8
|
||
- **`manifest.json`**: domain, version, requirements (`aiofiles>=23.2.1`), IoT class
|
||
- **`hacs.json`**: HA 2025.10.0+, HACS 2.0.1+
|
||
|
||
### Architecture
|
||
|
||
- **Data Flow**: API → Coordinator → Sensors/Binary Sensors
|
||
- **Storage**: HA Storage API for caching
|
||
- **Update**: Polling (cloud_polling)
|
||
- **Services**: get_price, get_apexcharts_data, get_apexcharts_yaml, refresh_user_data
|
||
|
||
### Common Tasks
|
||
|
||
- **Add sensor**: Edit `sensor.py`/`binary_sensor.py` + translation keys
|
||
- **Modify API**: Edit `api.py` (GraphQL queries)
|
||
- **Price calculations**: Edit `price_utils.py`
|
||
- **Translations**: Sync all files in `translations/` and `custom_translations/`
|
||
- **Add service**: Edit `services.py` + `services.yaml`
|
||
|
||
## Linting Rules (Ruff)
|
||
|
||
Key enforced rules:
|
||
|
||
- F401, F841: No unused imports/variables
|
||
- E402: Imports at top
|
||
- E501: Lines ≤120 chars
|
||
- C901, PLR0912, PLR0915: Simple functions
|
||
- PLR0911, RET504: No redundant else after return
|
||
- B008: No mutable defaults
|
||
- T201: No print()
|
||
- SIM102: Prefer `if x` over `if x == True`
|
||
|
||
## Optional Files
|
||
|
||
Only create if needed: `services.yaml`, `translations/*.json`, `binary_sensor.py`, `diagnostics.py`. **Avoid** Core-only files: `device_action.py`, `device_trigger.py`, `strings.json`.
|
||
|
||
## Important Notes
|
||
|
||
- **Only dependency**: `aiofiles>=23.2.1`
|
||
- **No pip install HA**: Use devcontainer
|
||
- **Git ignore**: `__pycache__`, `.pytest*`, `.ruff_cache`, `config/*` (except `configuration.yaml`)
|
||
- **Trust these instructions**: Only search if incomplete or incorrect
|