Commit graph

1,094 commits

Author SHA1 Message Date
Casey
e59ccfa571 Auto-fix unused imports across tests + switch.py (ruff --fix)
12 unused-import warnings cleaned up by `ruff check --select=F,I --fix
--unsafe-fixes`. No behavioral changes; 94/94 tests still green.

Remaining lint warnings (line-length, complexity) are accumulated
upstream tech debt outside this change's scope.
2026-05-16 15:12:19 +02:00
Casey
03d2748cd4 Group 7: tests — 94 passing in 0.57s (53/53 + 9.4 deferred)
Test infrastructure:
- Add `pytest-homeassistant-custom-component` (PHACC) as a `test`
  dependency group. PHACC ships `hass`, `enable_custom_integrations`,
  `MockConfigEntry`, and friends without needing to clone HA core as a
  sibling directory. Modernizes the test setup from upstream's
  `setup-symlinks` pattern.
- conftest.py: add `auto_enable_custom_integrations` autouse fixture
  so HA discovers the integration under `custom_components/` during
  tests. Keep the upstream template-deprecation no-op.
- Import paths: all tests now import from `custom_components.adaptive_lighting`
  (not `homeassistant.components.adaptive_lighting`) and from
  `pytest_homeassistant_custom_component.common` (not `tests.common`).

New tests (groups 7.2-7.16):
- tests/test_color_and_brightness.py (16 tests): TestBrightnessCurve
  asserts min-before-sunrise, midpoint-at-event, max-during-day, sunset
  ramp symmetry. TestColorTempCurve verifies the same shape applies to
  K. TestSunPosition checks the synthetic +1/-1/0 derivation.
  TestTanhDayCurveDirect exercises the helper directly.
- tests/test_config_flow.py (12 tests): six sections in order, each
  section contains only its specified fields, conditional visibility
  of send_split_delay, default sun entities, strict-typed entity
  selectors, NumberSelector slider/box configs, BooleanSelector for
  every flag, full user→create-entry flow, YAML-managed entry aborts
  with `yaml_managed` reason, options flow renders the sectioned schema.
- tests/test_init.py (6 tests): successful setup on current version,
  stale version raises ConfigEntryError via async_migrate_entry,
  unload is clean, tombstone removes orphan sleep entity + logs INFO,
  tombstone is idempotent, tombstone respects config_entry ownership.

Source modernizations driven by the tests:
- __init__.py: add `async_migrate_entry` that surfaces the
  "incompatible — delete and recreate" message and sets the entry to
  MIGRATION_ERROR. Removed direct `ConfigEntryError` from
  `async_setup_entry` (HA routes version mismatches through the
  migration handler now).
- switch.py: removed upstream's YAML-managed-entry auto-remove hack.
  YAML profiles now load normally and the options flow handles the
  "you must edit configuration.yaml" message (spec R7).

Existing tests updated to PHACC paths: test_adaptation_utils.py
(38 tests), test_hass_utils.py (22 tests). Both pass without
modification beyond the import fix.

Deleted: tests/test_switch.py (2,999 LOC of upstream tests, most
covering sleep mode / take-over-control / manual-control state
machines that no longer exist; CDiT-specific switch tests deferred
to a follow-up change).

Result: `uv run --group test pytest tests/` → 94 passed in 0.57s.

Deferred from this change:
- 4.3: manual UI test that toggling a field and saving reloads cleanly
  (requires a real HA instance, can't be done from CLI).
- 9.4: GitHub repo description / topics update (do via `gh repo edit`
  outside the change scope).

openspec status: 4/4 artifacts complete; strict-validate green.
2026-05-16 15:11:49 +02:00
Casey
bb3b8b81f4 Groups 8 + 9: strings, services.yaml, README, CHANGELOG (37/53)
strings.json + translations/en.json:
- Rewritten from scratch with plain-language labels and one-sentence
  framers per section (Targets / Daytime curve / Sun schedule / Light
  control / Advanced / Diagnostics).
- Per-field `data_description` for every visible option in the options
  flow.
- New translations for `yaml_managed` abort and the version-incompatible
  error.
- Removed every key for the 21 dropped fields and the sleep switch.
- Services section updated for the trimmed surface: dropped
  `set_manual_control` entirely, removed all sleep / take-over /
  sunrise-sunset-time keys from `change_switch_settings`.

services.yaml: rewritten by hand (was auto-generated upstream). Now
matches the fork's actual service surface: `apply` and
`change_switch_settings` only, with native HA selectors and units.

README: added a CDiT preamble at the top covering the five core
differences from upstream, the strict-version-break warning, the
recommended Sun2 companion, and the minimum HA version pin. Crucially,
also added a "🙏 Huge thanks to the upstream team" block that names
@basnijholt and the 130+ upstream contributors, points users at the
upstream repo for the canonical install, and routes core-curve / light-
handling bugs to upstream's tracker. Open-source credit done right.

CHANGELOG.md: new file. Header credits upstream up front; v2.0.0-cdit.1
section lists every Added / Changed / Removed item by name, the
migration / upgrade steps in numbered form, internal refactors, and
known limitations (Manager bridge stubs, locale drift, astral as
transitive dep).

tasks.md: 8.1-8.6 and 9.1-9.3 marked complete; 9.4 (GitHub repo
description) deferred to a separate `gh repo edit` step.

openspec validate cdit-config-redesign --strict: green.
JSON + YAML syntax: validated.
Module import: clean.
2026-05-16 14:59:09 +02:00
Casey
501e3d639e Implement cdit-config-redesign groups 1-6 (30/53 tasks)
const.py:
- Drop 21 retired CONF_*/DEFAULT_* (sleep cluster, manual sun timing,
  brightness curve variants, take-over-control cluster).
- Add CONF_SUNRISE_ENTITY / CONF_SUNSET_ENTITY (default
  sensor.sun_next_rising / _setting).
- Add RAMP_HALF_WIDTH_SECONDS = 1800.
- Add CONFIG_ENTRY_VERSION = 2 (gate for strict version-break).
- Re-default DEFAULT_MIN_BRIGHTNESS 1→5, DEFAULT_MIN_COLOR_TEMP 2000→2200.
- Update ICON_MAIN / _BRIGHTNESS / _COLOR_TEMP to the CDiT picks.

manifest.json: bump to 2.0.0-cdit.1, pin homeassistant: 2025.1.0,
re-point codeowners/documentation/issue_tracker to the CaseyRo fork.

switch.py:
- Drop sleep_mode_switch creation in async_setup_entry; integration
  now creates 3 switches per profile (master, adapt_color, adapt_brightness).
- Strip sleep-mode state machine from AdaptiveSwitch (sleep_mode_switch
  attribute, sleep_transition, adapt_until_sleep, the state-change
  listener, the _sleep_mode_switch_state_event_action method).
- Bridge-stub _take_over_control / _detect_non_ha_changes /
  _adapt_only_on_bare_turn_on / _only_once / _auto_reset_manual_control_time
  as class-level False/0 so Manager-side branches become dead code without
  needing a full rewrite of AdaptiveLightingManager.
- Remove handle_set_manual_control service + its registration.
- Replace astral-driven curve init with the new SunLightSettings call
  shape; add AdaptiveSwitch._today_sun_events() helper that reads the
  configured sunrise/sunset entities.
- Set _attr_icon on AdaptiveSwitch.

color_and_brightness.py:
- Rewrite SunLightSettings as a pure curve-math wrapper (5 fields:
  name + bounds + ramp half-width); methods take t_sunrise/t_sunset
  as args, never reads HA state.
- Implement piecewise tanh ramp curve per spec R4 / design D11 in
  _tanh_day_curve(). Both brightness and color-temp use the same shape.
- Drop SunEvents, sleep-mode branches, brightness_mode-switch, astral
  dependency, force_rgb_color, lerp_color_hsv sleep-tinted color blending.

config_flow.py:
- Rewrite as sectioned schema (Targets / Daytime curve / Sun schedule /
  Light control / Advanced / Diagnostics) via HA's section() helper.
- Native HA selectors throughout (NumberSelector, EntitySelector,
  BooleanSelector). Strict typing on sun-event entity pickers.
- Conditional visibility for send_split_delay (driver:
  separate_turn_on_commands).
- Extend OptionsFlowWithReload (with ImportError fallback for HA < 2025.1
  dev environment); async_abort(reason="yaml_managed") for SOURCE_IMPORT.
- VERSION = CONFIG_ENTRY_VERSION.

__init__.py:
- Reject older config entries with ConfigEntryError ("recreate the entry")
  per spec R8 / design D4.
- Add _remove_orphan_sleep_entities tombstone helper that scans the
  entity registry for sleep-mode entities owned by this entry and
  removes them on first setup. Idempotent and config_entry-scoped.

_docs_helpers.py: stub the removed DOCS_MANUAL_CONTROL / SET_MANUAL_CONTROL_SCHEMA
so the docs-generator script keeps importing.

Validation:
- ALL modules import cleanly under HA 2024.12.5 (dev env).
- openspec validate cdit-config-redesign --strict: green.
- ruff check --select=F: clean.

Remaining: groups 7 (16 tests), 8 (strings + plain-language pass), 9 (docs).
2026-05-16 14:27:39 +02:00
Casey
e4efcfa830 Add UX polish tasks to cdit-config-redesign
Three new checkboxes captured from the design-review thread:
- 1.6 better defaults (min_brightness 1→5, min_color_temp 2000→2200)
- 2.5 distinct mdi icons on each switch class
- 8.6 plain-language pass on every label, description, and error

Adds a 'polish' annotation tag for quality tasks that do not map
to a numbered requirement or design decision.
2026-05-16 13:16:43 +02:00
Casey
b9cfce5e02 Add lovelace-card change: proposal + design
Forward-looking change that adds a single-profile Lovelace card
visualizing AL state — current brightness, color temperature,
24-hour curve, the three switches, the four range sliders, and an
optional house-mode badge. Card is additive: it consumes existing
entities and never replaces them.

Stack: Lit + TypeScript + Vite, bundled alongside the integration
via HACS. Visual direction: editorial-instrument — calm typography,
restrained color, the card warms after sunset.

Specs and tasks deferred until prerequisites land (cdit-config-
redesign for the 3-switch model and sun-entity sensors,
add-runtime-range-controls for the four number entities the
sliders bind to).
2026-05-16 13:15:57 +02:00
Casey
80f99db16f Scaffold CDiT fork: planning artifacts and tooling
- openspec/ — three changes scoped:
  • cdit-config-redesign: full artifact set (proposal + design + specs +
    tasks), strict-validate green. Prunes 21 fields from the upstream
    options flow, switches sun timing to entity-driven sources, hardcodes
    a tanh curve, and breaks compat with upstream config entries.
  • add-runtime-range-controls: proposal stub for promoting the 4
    brightness/color-temp ranges to live number entities.
  • house-mode-modes: proposal stub for per-AL house-mode behavior matrix
    driving the runtime switches.
- .claude/ — opsx slash commands and openspec skill bundles for driving
  the artifact-driven workflow.
- CLAUDE.md — fork orientation, remote topology, dev commands, and the
  active change pointer.
2026-05-16 12:24:34 +02:00
renovate[bot]
ddaf851be3
⬆️ Update release-drafter/release-drafter action to v7
Squash merge Renovate GitHub Actions update.

Validation:
- Fixed PR-time Release Drafter v7 execution by using dry-run for pull_request events.
- GitHub Actions checks for PR #1445 passed before merge.
2026-04-24 14:55:04 -07:00
renovate[bot]
89b5e9a14f
⬆️ Update docker/setup-qemu-action action to v4
Squash merge Renovate GitHub Actions update.

Validation:
- GitHub Actions checks for PR #1438 passed before merge.
2026-04-24 14:23:26 -07:00
Florian
830c5589f7
fix: reduce log verbosity for self-triggered off-to-on warning (#1433) (#1434)
* fix: reduce log verbosity for self-triggered off-to-on warning (#1433)

Move full event object dump from warning to debug level in
_off_to_on_state_event_is_from_turn_on() (switch.py:2717).

For lights with large effect_list attributes (e.g. Govee lights
with 130+ effects), the warning dumped the entire Event object
including both old_state and new_state, creating log entries
thousands of characters long.

The warning now logs only entity_id and context.id, while the
full event remains available at debug level for troubleshooting.

Fixes #1433

* fix: correct indentation for _LOGGER.debug block

* fix: correct indentation for _LOGGER.warning and _LOGGER.debug

* fix: remove unintended encoding corruption, keep only log level change

Reset switch.py to main and re-apply only the intended change:
move the full event object from warning to debug level in
_off_to_on_state_event_is_from_turn_on().

Addresses reviewer feedback about unintended Unicode corruption
(→ and ≈ characters were corrupted to mojibake).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Florian Horner <florianhorner@Mac.fritz.box>
Co-authored-by: Bas Nijholt <basnijholt@users.noreply.github.com>
2026-04-24 13:30:18 -07:00
renovate[bot]
7dcad99d81
⬆️ Update docker/setup-buildx-action action to v4 (#1439)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 13:13:53 -07:00
renovate[bot]
cb4eb7ef49
⬆️ Update actions/deploy-pages action to v5 (#1453)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 13:13:34 -07:00
renovate[bot]
17e43e0427
⬆️ Update astral-sh/setup-uv action to v8 (#1468)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 13:13:15 -07:00
Florian
b787c533bf
fix: make setup-dependencies portable on macOS (#1463)
Two issues prevented the script from running on macOS without manual intervention:

1. `sed -i` requires a backup suffix on macOS BSD sed. Replace with a
   portable `grep -v | mv` idiom that works on both macOS and Linux.

2. `python` is not in PATH on macOS by default. Replace with `python3`.

Co-authored-by: Florian Horner <florianhorner@macbook-pro-von-florian.tail6f28f8.ts.net>
Co-authored-by: Bas Nijholt <basnijholt@users.noreply.github.com>
2026-04-24 13:12:20 -07:00
renovate[bot]
c8c31be573
⬆️ Update actions/upload-pages-artifact action to v5 (#1467)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 13:12:01 -07:00
renovate[bot]
86091de0e7
⬆️ Update docker/login-action action to v4 (#1437)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 12:00:21 -07:00
renovate[bot]
31762ba78d
⬆️ Update docker/metadata-action action to v6 (#1440)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 12:00:10 -07:00
renovate[bot]
0a305a7a4c
⬆️ Update docker/build-push-action action to v7 (#1441)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 11:59:38 -07:00
Bas Nijholt
c4b8e28ea8
fix: restore hassfest and Home Assistant CI
## Summary
- fix hassfest validation by replacing raw options-description URLs with Home Assistant translation placeholders
- extend the pytest CI matrix to cover the latest patch release for each Home Assistant month, plus dev
- align CI/dev container Python versions and tests with newer Home Assistant behavior

## Validation
- GitHub Actions pytest matrix passed for 2024.12.5 through 2026.4.3 plus dev
- Docker passed for linux/amd64 and linux/arm64
- hassfest, HACS validation, pre-commit, pre-commit.ci, markdown-code-runner, docs build, and Release Drafter passed
2026-04-24 11:31:53 -07:00
Roee Hendel
6cebe14a69
fix: merge last_service_data across split calls to fix detect_non_ha_changes with separate_turn_on_commands (#1426)
* test: regression test — AL must not override manual brightness with separate_turn_on_commands

End-to-end scenario: user adjusts brightness via a directly-bound Zigbee
switch (e.g. IKEA RODRET).  No HA service call is made; ZHA reports the new
brightness via async_update_entity.  On the next adaptation interval AL must
detect the change and stop overriding the user's brightness.

The test verifies the user-visible symptom: after two adaptation cycles
following a simulated direct-Zigbee brightness change, the light's brightness
must still be the manually set value — not AL's own target.

NOTE: this test FAILS on the current code.  It is committed here to document
the bug before the fix is applied in the next commit.

* fix: merge last_service_data across split calls to fix detect_non_ha_changes with separate_turn_on_commands

When separate_turn_on_commands=True, each adaptation cycle makes two
light.turn_on calls (brightness, then color_temp).  Previously each call
overwrote last_service_data[light], so after the cycle only the color_temp
key remained.  _attributes_have_changed() then saw old_brightness=None and
silently skipped the brightness comparison, so a manually-set brightness was
never detected and AL kept overriding it.

Fix: merge instead of overwrite so all split-call attributes accumulate:

    self.manager.last_service_data[light] = {
        **self.manager.last_service_data.get(light, {}),
        **service_data,
    }

* test: add intermediate assertions to regression test

Two assertions were promised in the PR description but missing:
1. After the force-adapt, assert that last_service_data contains BOTH
   brightness AND color — directly proving the merge fix works.
2. After the first non-forced update, assert that BRIGHTNESS is in
   manual_control — proving detection fired, not just that the final
   state is right.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* refactor: remove spurious comments, trim test docstring and assertions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* refactor: strip verbose comments from test, trim assert messages

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* test: add message to bare assert
2026-03-16 15:54:53 -07:00
Bas Nijholt
f9ccc946ee
Migrate to markdown-code-runner's built-in include_section() (#1417) 2026-01-26 09:01:50 +01:00
renovate[bot]
74a795d907
⬆️ Update actions/checkout action to v6.0.2 (#1411)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-01-22 23:02:25 +00:00
allcontributors[bot]
e9f7d4925f
docs: add Esspel as a contributor for translation (#1409)
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2026-01-20 03:20:18 -08:00
allcontributors[bot]
ec33670b3f
docs: add Yllelder as a contributor for translation (#1408)
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2026-01-20 03:19:00 -08:00
allcontributors[bot]
2fdc2a1636
docs: add NatanDosAnjos as a contributor for translation (#1407)
* docs: update README.md

* docs: update .all-contributorsrc

---------

Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com>
2026-01-20 03:18:04 -08:00
allcontributors[bot]
7317c2966d
docs: add ademuri as a contributor for code (#1406) 2026-01-20 07:36:36 +00:00
Adam DeMuri
5b7153a9a1 Automated update of docs/troubleshooting.md 2026-01-20 01:10:17 +00:00
Adam DeMuri
d964c861d5 Fix the markdown-code-runner workflow.
This fixes the workflow to work for pull requests in addition to pushes:
- Correctly determines the repository and branch
- For pull requests, if there are changes, fails with a message to make
  the changes locally
- Extracts the commands to update generated files into a script
2026-01-20 01:10:17 +00:00
Adam DeMuri
f7a7226fdb
Fix Docker warning by removing unbound variable (#1400) 2026-01-19 17:03:40 +00:00
Adam DeMuri
e656dd31b0
Fix coverage. (#1404) 2026-01-19 17:03:20 +00:00
Adam DeMuri
ae719a676d Add core/ to .gitignore 2026-01-17 08:34:46 +01:00
allcontributors[bot]
d60ba75014
docs: add andrei-lazarov as a contributor for doc (#1397) 2026-01-14 19:28:08 +01:00
Andrei LAZAROV
da732ae1a1
📝 Update readme: Modern lights are routers (#1396) 2026-01-14 19:27:19 +01:00
Mario Guggenberger
844afc081a
build: fix tasks not executing in dev container (#1394) 2026-01-13 11:32:17 +01:00
renovate[bot]
fcff6d48ec
⬆️ Update astral-sh/setup-uv action to v7 (#1392) 2026-01-13 09:07:28 +01:00
renovate[bot]
093376dbed
⬆️ Update actions/setup-python action to v6 (#1390) 2026-01-13 09:06:58 +01:00
renovate[bot]
455040e532
⬆️ Update actions/checkout action to v6 (#1389) 2026-01-13 09:06:42 +01:00
Bas Nijholt
eb25df01d5
Enable custom analytics provider for Plausible (#1388) 2026-01-12 23:50:55 +01:00
renovate[bot]
9480211e1b ⬆️ Update python to v3.14.2 2026-01-12 23:49:27 +01:00
renovate[bot]
a1ddbc000f ⬆️ Pin dependencies 2026-01-12 23:46:08 +01:00
Bas Nijholt
cbbcabdd1f
Add documentation site with Zensical framework (#1385)
* Add documentation site with Zensical framework

Create comprehensive documentation site for adaptive-lighting.nijho.lt:

- Add zensical.toml configuration with Material theme (amber/orange)
- Create docs_gen.py module for extracting README sections via markers
- Add section markers to README.md for content reuse
- Create documentation pages:
  - index.md: Home with features overview
  - getting-started.md: Installation and quick setup
  - configuration.md: Auto-generated config options table
  - services.md: Auto-generated service documentation
  - automation-examples.md: Real-world automation recipes
  - troubleshooting.md: Common issues and solutions
  - see-also.md: External resources and links
  - advanced/brightness-modes.md: Brightness mode deep dive
  - advanced/manual-control.md: Manual control system docs
  - advanced/sleep-mode.md: Sleep mode configuration
- Add GitHub Actions workflow for building and deploying to Pages
- Add custom CSS with sun-themed styling
- Add CNAME for custom domain

Uses markdown-code-runner to auto-generate content from code schemas
and extract README sections for single-source documentation.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Remove duplicated content from docs, make pages thin wrappers

- troubleshooting.md: Remove manually written "Additional Tips" section
- automation-examples.md: Remove duplicate "Additional Examples" section
- configuration.md: Remove duplicate "Option Categories" tables
- sleep-mode.md: Simplify to reference main config, remove duplicate examples
- docs_gen.py: Remove unused get_troubleshooting() and get_sleep_mode_intro()

This reduces duplication risk by keeping README as single source of truth.
Docs pages now primarily pull content via markdown-code-runner.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Integrate webapp (simulator) into docs workflow

- Merge deploy-webapp.yml into docs.yml workflow
- Build simulator and place at /simulator/ subdirectory
- Update docs links to use relative paths to simulator
- Remove separate deploy-webapp.yml to avoid conflicts

The combined workflow now:
1. Builds docs with zensical
2. Builds webapp with shinylive
3. Copies webapp to site/simulator/
4. Deploys everything to GitHub Pages

Simulator will be at adaptive-lighting.nijho.lt/simulator/

* Fix pre-commit and CI issues

- Add site_name to zensical.toml (required by MkDocs)
- Fix RET504 in docs_gen.py (unnecessary assignment before return)
- Remove docs/run_markdown_code_runner.py (lint issues, not needed for CI)

* Fix _docs_helpers.py import error in CI

- Add try/except for relative vs absolute imports in _docs_helpers.py
- Remove silent error handling in docs workflow (fail on error)

The relative import fails when markdown-code-runner executes the code
directly via sys.path.insert. The fallback to absolute import fixes this.

* Temporarily enable deployment from feature branch

* Add tabulate dependency for pandas to_markdown()

* Fix theme configuration for proper light/dark mode

- Restructure zensical.toml to match working agent-cli config
- Add three-way palette toggle (system/light/dark)
- Use proper [project.theme] structure
- Simplify extra.css to not override theme colors
- Add Inter font for text, JetBrains Mono for code

* Add Plausible analytics and fix homepage navigation

- Add custom analytics override for plausible.nijho.lt tracking
- Remove hide:navigation from index.md to show menu on homepage

* Remove temporary feature branch deployment settings

Revert to main-only deployment for docs workflow before merging.

* Revert "Remove temporary feature branch deployment settings"

This reverts commit c568694837.

* Add markdown-gfm-admonition for GitHub-style admonitions

The zensical build was failing silently because gfm_admonition extension
was not installed. Add the dependency to pyproject.toml and docs workflow.

* Use uv sync for documentation dependencies

Switch from manual pip installs to uv sync with pyproject.toml for cleaner
dependency management and reproducible builds.

* Fix markdown rendering inside details blocks

Enable md_in_html extension and add markdown="1" attribute to <details>
tags so markdown content inside them is properly rendered.

* Remove emojis from manually written documentation

Keep emojis in auto-generated content from README, but remove from
manually maintained docs in favor of clean text and Material icons.

* Enable attr_list extension for button styling

* Improve pyproject.toml and use GitHub-style admonitions

- Add accurate project metadata (version, authors, classifiers, URLs)
- Organize dependency groups: docs, dev, test
- Add tool configs for ruff, mypy, pytest
- Convert MkDocs-style admonitions (!!! tip) to GitHub-style (> [!TIP])
- Use docs group in CI workflow

* Add homeassistant and ulid-transform as runtime dependencies

Remove speculative test dependencies since tests run inside HA core.

* Simplify docs_gen.py - remove wrapper functions

Use readme_section() directly in docs instead of 10 one-liner wrappers.
Changed default strip_heading to True since that's the common case.

* Populate empty OUTPUT sections with markdown-code-runner

* Add markdown-code-runner workflow for auto-updating docs

- Add docs/run_markdown_code_runner.py script to process all docs
- Add GitHub workflow to run on push/PR and auto-commit changes

* Exclude README.md from markdown-code-runner workflow

README.md contains code blocks that import from
homeassistant.components.adaptive_lighting, which only exists
when running inside Home Assistant core, not in a regular venv.

* Update auto-generated docs

* Use editable install for markdown-code-runner workflow

- Add setuptools.packages.find config pointing to custom_components
- Remove sys.path.insert manipulation from all docs files
- Update imports to use adaptive_lighting.* package paths
- Install package with `uv pip install -e .` in workflow
- Remove deprecated license classifier (PEP 639)

* Consolidate markdown-code-runner into single workflow

- Remove separate markdown-code-runner.yml workflow
- Update update-readme.yml to handle all markdown files (docs + README)
- Rename workflow to "Update auto-generated content"
- Update README imports to use adaptive_lighting package path

* Rename workflow to markdown-code-runner

* Remove accidentally committed files

* Remove redundant markdown-code-runner from docs workflow

* Fix: use uv pip install instead of uv add in CI

* Add webapp deps (astral, shinylive) to docs group

* Remove unused install_dependencies action

* Update to latest action versions (uv@v5, upload-pages-artifact@v4)

* Remove try/except import fallback in _docs_helpers.py

* Restore install_dependencies action (used by pytest)

* Simplify docs workflow: run on all pushes/PRs

* Simplify mcr workflow paths; revert install_dependencies to main

* Remove redundant cp+sed for webapp (file already in repo)

* Fix mcr push: pull --rebase before push

* Fix mcr: checkout PR branch instead of detached HEAD

* Update auto-generated content

* Switch from setuptools to hatch build system

Replace [tool.setuptools.packages.find] with [tool.hatch.build.targets.wheel]
for hatchling compatibility.

* Update auto-generated content

* Move homeassistant deps to docs group

This is a HA custom component, not a pip package. The homeassistant
dependency is only needed for docs building, not as a project dependency.

* Update auto-generated content

* Remove PyPI-only metadata from pyproject.toml

* Remove arbitrary version constraints from dependency groups

* Update auto-generated content

* Remove unused troubleshooting section markers from README

* Remove temporary feature branch settings from docs workflow

* Use GitHub admonition syntax for warning in change_switch_settings section

* Update auto-generated content
2026-01-12 23:39:57 +01:00
Bas Nijholt
e0f812d406
Bump to v1.30.1 (#1384) v1.30.1 2026-01-12 13:46:19 +01:00
Bas Nijholt
e61a018616
Fix regression: lights not adapting when turned on by automation (#1380)
## Summary

- Fixes regression in v1.30.0 where lights turned on by automations were incorrectly marked as "manually controlled"
- Makes `adapt_only_on_bare_turn_on` respect individual attribute tracking from #1356

## Root Cause

PR #1356 added a call to `update_manually_controlled_from_event()` in the `turn_on_off_event_listener.on()` handler for ALL `light.turn_on` events, including when turning a light on from OFF state.

When an automation turns on a light with brightness/color attributes, this incorrectly marked the light as "manually controlled", preventing Adaptive Lighting from adapting it.

## Fix

1. Only call `update_manually_controlled_from_event()` when the light was **already ON** before the turn_on event. Turning on from OFF is handled by `_respond_to_off_to_on_event()`.

2. Make `adapt_only_on_bare_turn_on` respect `take_over_control_mode`:
   - With `PAUSE_CHANGED`: Only pause adaptation of specified attributes, continue adapting unspecified ones
   - With `PAUSE_ALL`: Pause all adaptation (existing behavior)

## Expected Behavior After Fix

| Scenario | `adapt_only_on_bare_turn_on` | `take_over_control_mode` | Result |
|----------|------------------------------|--------------------------|--------|
| Turn on from OFF with brightness | `false` | Either | NOT manually controlled |
| Turn on from OFF with brightness | `true` | `PAUSE_ALL` | All adaptation paused |
| Turn on from OFF with brightness | `true` | `PAUSE_CHANGED` | Only brightness paused, color adapts |
| Turn on from OFF without attributes | Either | Either | NOT manually controlled |
| Change brightness while ON | Either | Either | Brightness manually controlled |

## Test plan

- [x] Turn on light via automation with brightness/color (`adapt_only_on_bare_turn_on=false`) - should adapt
- [x] Turn on light via scene (`adapt_only_on_bare_turn_on=true`, `PAUSE_ALL`) - should pause all adaptation
- [x] Turn on light with brightness only (`adapt_only_on_bare_turn_on=true`, `PAUSE_CHANGED`) - should adapt color
- [x] Both intercept=True and intercept=False paths tested for consistency
- [x] CI tests pass

Fixes #1378

Co-authored-by: Mario Guggenberger <mg@protyposis.net>
2026-01-12 13:40:55 +01:00
Bas Nijholt
49f9da14fe
docs: clarify Docker test setup requirements (#1383) 2026-01-11 21:57:52 +01:00
Bas Nijholt
f95093e1dc Bump to v1.30.0 v1.30.0 2026-01-05 12:43:07 -08:00
Mario Guggenberger
f84ee445b7
Individual manual control of brightness and color (#1356)
* refactor: introduce light control parameter enum

* refactor: replace manual control flag with parameter enum

* test: update deprecated color temp attribute

* build: set execution bits on task scripts

* feat: individual manual control of brightness and color

* test: add tests for individual manual control evaluation

* fix: sequential manual changes not always detected

If multiple attributes of a light were changed within an interval, only the last change was detected because the check in the interval only used the latest event. For example, if there was a brightness change and a following color change, only the color attribute was detected as manually controlled. To fix this, the manual control attribute flags are now set directly from the event handler so that all events are processed.

* fix: invalid service description

* docs: fix missing space in config description

* refactor: pluralize multivalued bitmask enum name
2025-12-22 22:55:16 -08:00
Weblate (bot)
2f599d6e1b
Translations update from Hosted Weblate (#1331)
* Translated using Weblate (German)

Currently translated at 100.0% (156 of 156 strings)

Co-authored-by: Anton <ihrkenntmichnicht@posteo.de>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/adaptive-lighting/adaptive-lighting/de/
Translation: Adaptive Lighting/Adaptive Lighting

* Translated using Weblate (Catalan)

Currently translated at 100.0% (156 of 156 strings)

Co-authored-by: Enric Pagès i Gassull <enricpages@hotmail.com>
Translate-URL: https://hosted.weblate.org/projects/adaptive-lighting/adaptive-lighting/ca/
Translation: Adaptive Lighting/Adaptive Lighting

---------

Co-authored-by: Anton <ihrkenntmichnicht@posteo.de>
Co-authored-by: Enric Pagès i Gassull <enricpages@hotmail.com>
2025-12-12 14:00:30 -08:00
renovate[bot]
828f73d481
⬆️ Update actions/checkout action to v6 (#1352)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-12-12 13:59:40 -08:00
lenucksi
9c7a95f696
fix(ci): fix broken Docker workflow and modernize (#1318)
* fix(ci): fix broken Docker workflow and modernize

## Critical Bug Fixes

1. **Fix broken push condition** (CRITICAL):
   - Old: `push: ${{ github.ref == 'refs/heads/master' }}`
   - Problem: Branch renamed to `main`, so images NEVER pushed
   - New: `push: ${{ github.event_name != 'pull_request' }}`
   - Result: Docker images will actually be published again

2. **Add missing checkout step**:
   - Build was failing because source code wasn't checked out
   - Required for Docker build context

## Modernization Improvements

3. **Migrate to GitHub Container Registry (GHCR)**:
   - Old: DockerHub with `DOCKERHUB_USERNAME` and `DOCKERHUB_TOKEN` secrets
   - New: GHCR with built-in `GITHUB_TOKEN`
   - Benefits: No external account required, better integration

4. **Add semantic versioning**:
   - Automatically tags releases: `v1.2.3`, `v1.2`, `v1`, `latest`
   - Supports version tags (v*), branches, and PRs
   - Uses docker/metadata-action for automatic tagging

5. **Add GitHub Actions caching**:
   - Uses `type=gha` cache for faster builds
   - Reduces build times and GitHub Actions minutes

6. **Security: Digest pinning**:
   - All actions pinned to commit SHAs
   - Prevents supply chain attacks via tag manipulation
   - Follows security best practices

7. **Add explicit permissions**:
   - Minimal required permissions (contents: read, packages: write)
   - Follows principle of least privilege

8. **Add workflow triggers**:
   - Tags (v*) for releases
   - Pull requests for testing
   - Manual dispatch for on-demand builds

## Testing

- Workflow syntax validated
- Push logic tested with different event types
- Compatible with existing Docker build process

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

* refactor(ci): simplify docker workflow

- Use version tags instead of SHA pins for readability
- Remove verbose step names (action names are self-documenting)
- Compact YAML formatting
- Fix actions/checkout to v4 (v6 doesn't exist)

---------

Co-authored-by: Bas Nijholt <bas@nijho.lt>
2025-12-12 13:49:45 -08:00
Mario Guggenberger
79973fb71d
chore(devcontainer): fix Pylance resolution of HA core modules (#1343) 2025-12-12 13:38:35 -08:00