mirror of
https://github.com/basnijholt/adaptive-lighting.git
synced 2026-09-20 18:54:03 +02:00
The CDiT fork is single-household and was carrying an entire upstream docs/ mkdocs site documenting features the fork has removed (sleep mode, take-over-control, brightness_mode selector, YAML config). The README mostly auto-generated from those pages via markdown-code-runner. What's gone: - docs/ — all 11 pages + assets + run_markdown_code_runner.py - .github/workflows/docs.yml — zensical+shinylive GitHub Pages build - .github/workflows/markdown-code-runner.yml — auto-edit of README from docs/ - .github/update-services.py / update-strings.py — would clobber the hand-edited services.yaml / strings.json - scripts/update-generated-content — orchestrator for the above - custom_components/adaptive_lighting/_docs_helpers.py + docs_gen.py — only used by the deleted markdown-code-runner - zensical.toml — docs-site config - "docs" dependency group in pyproject.toml (markdown-code-runner, shinylive, zensical, etc.) + lock regenerated What's new: - README.md rewritten to describe the fork's actual surface — 3 switches, 4 number entities, 3 sensor entities per profile, 2 services (apply + change_switch_settings), entry-only setup, UI tuning, sun source. Preserves the existing "What's new in 2.1" / "2.2" block quotes. - webapp/README.md annotated to flag the Shiny simulator models the upstream curve (with brightness_mode, sleep mode, etc.) and does not reflect the fork. - CLAUDE.md command table no longer references update-generated-content. Sensor.py + test_sensor_platform.py: incidental black reformat from the lint pass (multi-arg function calls split per line). Tests still pass (123/123). Lint clean. Sensors implementation unchanged.
106 lines
5.9 KiB
Markdown
106 lines
5.9 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## What this is
|
|
|
|
A CDiT fork of [basnijholt/adaptive-lighting](https://github.com/basnijholt/adaptive-lighting) — a Home Assistant custom component that adjusts light brightness and color temperature in sync with the sun curve. The fork is opinionated about CDiT's single-household setup and explicitly diverges from upstream on the integration's configuration surface.
|
|
|
|
**Fork is not a drop-in replacement.** Existing upstream config entries will fail to load (deliberate, see `openspec/changes/cdit-config-redesign/design.md` decision 4).
|
|
|
|
## Remote topology
|
|
|
|
```
|
|
origin git@github.com:CaseyRo/adaptive-lighting.git (the fork, read-write)
|
|
upstream https://github.com/basnijholt/adaptive-lighting.git (read-only)
|
|
```
|
|
|
|
Sync upstream changes:
|
|
|
|
```bash
|
|
git fetch upstream
|
|
git merge upstream/main # or rebase, depending on local policy
|
|
# resolve conflicts under custom_components/adaptive_lighting/
|
|
```
|
|
|
|
## Commands
|
|
|
|
Python tooling is `uv` (not `pip` or `poetry`). All commands assume an activated venv from `./scripts/setup-devcontainer`.
|
|
|
|
| Task | Command |
|
|
|---|---|
|
|
| Run the test suite | `uv run pytest` |
|
|
| Run a single test | `uv run pytest tests/test_config_flow.py::test_options_flow_init` |
|
|
| Lint everything (pre-commit) | `./scripts/lint` |
|
|
| Run HA locally with the custom component loaded | `./scripts/develop` (boots HA on `localhost:8123` from `./config/`) |
|
|
| Refresh test matrix | `./scripts/update-test-matrix.py` |
|
|
|
|
Ruff config lives in `.ruff.toml`. Pre-commit hooks in `.pre-commit-config.yaml`. Both enforce on push via `./scripts/lint`.
|
|
|
|
## Architecture
|
|
|
|
This is a standard Home Assistant **custom component** packaged under `custom_components/adaptive_lighting/`. HA loads it by directory name when present in a HA config's `custom_components/`. The HACS integration provides distribution.
|
|
|
|
Big-picture layout:
|
|
|
|
```
|
|
custom_components/adaptive_lighting/
|
|
├── __init__.py entry point: async_setup_entry, async_unload_entry,
|
|
│ and the curve math (sun-position + brightness/CT calc)
|
|
├── config_flow.py UI flow for setup and reconfiguration. Iterates
|
|
│ VALIDATION_TUPLES from const.py to build the schema.
|
|
├── switch.py the 4 switch entities per AL config (master, sleep,
|
|
│ adapt_color, adapt_brightness). After
|
|
│ cdit-config-redesign lands: 3 switches (no sleep).
|
|
├── const.py CONF_/DEFAULT_ constants + VALIDATION_TUPLES — the
|
|
│ single source for what fields exist in the schema.
|
|
├── color_and_brightness.py pure math: tanh, sun-elevation curve, color-temp
|
|
│ interpolation.
|
|
├── adaptation_utils.py per-light service-call shaping (intercept,
|
|
│ skip_redundant_commands, split commands, etc.)
|
|
├── hass_utils.py HA-specific helpers (entity registry lookups,
|
|
│ timestamps, service-call dispatch).
|
|
├── manifest.json integration metadata; `version` here gates
|
|
│ the strict break in cdit-config-redesign.
|
|
└── strings.json UI labels for the config flow, errors, abort reasons.
|
|
```
|
|
|
|
The CDiT fork is also planning two follow-on changes that layer cleanly on top:
|
|
- `add-runtime-range-controls` — adds a `number` platform with live entities for the 4 brightness/CT ranges.
|
|
- `house-mode-modes` — adds an `input_select`-driven behavior matrix that drives the 3 runtime switches on house-mode change.
|
|
|
|
Neither is implemented yet; both have proposal stubs in `openspec/changes/`.
|
|
|
|
## Planning workflow — OpenSpec under `opsx`
|
|
|
|
All non-trivial changes go through OpenSpec before code lands. The experimental `opsx` schema (artifact-driven: proposal → design → specs → tasks) is configured. Drive it via `.claude/commands/opsx/*` slash commands or the `openspec-*` skills.
|
|
|
|
```
|
|
openspec/
|
|
├── config.yaml (project context lives here once filled in)
|
|
├── specs/ long-lived capability specs (empty until a change archives)
|
|
└── changes/
|
|
├── cdit-config-redesign/ active, 4/4 artifacts, strict-validate green
|
|
│ ├── proposal.md why + what changes + capabilities + impact
|
|
│ ├── design.md 15 decisions with rejected alternatives, risks, migration
|
|
│ ├── specs/options-flow/spec.md 9 requirements, 22 Given/When/Then scenarios
|
|
│ └── tasks.md 9 task groups, 36 checkboxes with [R, D] annotations
|
|
├── add-runtime-range-controls/ stub, proposal only
|
|
└── house-mode-modes/ stub, proposal only
|
|
```
|
|
|
|
Validate any active change with:
|
|
|
|
```bash
|
|
openspec validate <change-name> --strict
|
|
```
|
|
|
|
When implementing tasks for an active change, prefer `/opsx:apply <change-name>` over manual edits — it walks `tasks.md` checkbox by checkbox. `/opsx:verify` checks the resulting code against the spec's scenarios before archive.
|
|
|
|
## Conventions worth preserving
|
|
|
|
- **Change names**: kebab-case (e.g., `cdit-config-redesign`, `add-runtime-range-controls`).
|
|
- **Capability slugs**: kebab-case, scoped tight (`options-flow`, `runtime-range-controls`, `house-mode-binding`) — not broad umbrellas.
|
|
- **Annotations in `tasks.md`**: each task ends with `[R…, D…]` referencing requirements in the change's spec delta and decisions in `design.md`. Keep traceability.
|
|
- **No silent migrations**: CDiT-fork breaking changes bump `manifest.json` major and reject incompatible config entries with a clear error (see `cdit-config-redesign` design decision 4).
|
|
- **`openspec/config.yaml` `context:` field**: still unset. Fill in once CDiT tech-stack conventions stabilize — it propagates into every artifact prompt.
|