Commit graph

1,104 commits

Author SHA1 Message Date
Casey
bba0ef31d8 Delete upstream docs apparatus; rewrite README for the fork
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.
2026-05-21 10:23:04 +02:00
Casey
1b21228b30 Implement add-output-sensors: 36/41 tasks complete
Three sensor entities per AL profile expose the curve's current outputs
plus actual sun elevation as graphable numerics with
SensorStateClass.MEASUREMENT, so HA's recorder + apexcharts-card chart
them natively:

- sensor.<profile>_output_brightness   (% — from self._settings)
- sensor.<profile>_output_color_temp   (K — from self._settings)
- sensor.<profile>_sun_elevation       (° — from sun.sun.attributes.elevation)

Architecture: master switch publishes computed outputs to
hass.data[DOMAIN][entry_id]["outputs"] after each curve tick, then fires
a per-entry dispatcher signal. Sensors subscribe and read from the cache.
Single computation path, push-based updates, no polling.

The existing master switch attributes (brightness_pct, color_temp_kelvin,
synthetic sun_position in [-1,+1]) are unchanged — sensors are purely
additive. Manifest bumped to 2.2.0-cdit.1 (minor; no breaking changes).

Artifact realignment along the way: Q2 answer assumed sun_position was
Sun2 elevation degrees, but reading color_and_brightness.py revealed
it's a synthetic float in [-1,+1] derived from the brightness curve.
Switched to pulling actual elevation from sun.sun (Decision 8 added),
renamed sensor from sun_position to sun_elevation. Friendly names use
asymmetric "Output" prefix to dodge collision with the adapt-brightness
switch and Min/Max color-temp numbers.

Remaining: group 6 (manual live-HA verification on
homeassistant.onca-blenny.ts.net) — requires HACS deploy.

15 new sensor tests pass; full suite green (123/123). openspec
validate --strict green. ruff clean on new files.
2026-05-21 10:11:52 +02:00
Casey
a6eb2dbe68 Propose add-output-sensors: 3 sensors per profile for recorder graphing
Promotes the master switch's current_brightness, current_color_temp, and
sun_position attributes to first-class sensor entities with
SensorStateClass.MEASUREMENT so HA's recorder graphs them as numerics.
This is the explicit complement to the killed add-lovelace-card: stock
apexcharts-card / History panel becomes the charting story once values
live on graphable entities.

Architecture: master switch publishes computed outputs to
hass.data[DOMAIN][entry_id]["outputs"] after each curve tick, then fires
a per-entry dispatcher signal. Sensors subscribe to the signal and read
from the cache. Single computation path; pure-reader sensors.

Naming: "Output brightness" / "Output color temp" disambiguate from
adapt-brightness switch and min/max number entities. "Sun position"
needs no prefix. sun_position is solar elevation in degrees (unit °)
sourced from the user's configured Sun2 / sensor.sun_* entity.

4 artifacts: proposal, design (8 decisions), spec (5 requirements, 13
scenarios), tasks (7 groups, 33 checkboxes). Strict-validate green.
2026-05-18 10:07:50 +02:00
Casey
70983a82f4 Drop house-mode-modes and add-lovelace-card change proposals
Both fail the "will the maintainer actually use this?" test for a
single-household fork:

- house-mode-modes: state-driven switch flips are what Node-RED already
  does in the CDiT stack. Pushing them into the integration competes
  with Node-RED's purpose and adds HA-core-churn maintenance forever.
- add-lovelace-card: maintainer wouldn't use a custom Lit + TypeScript +
  Vite + HACS plugin card. Stock tile + apexcharts cards in Lovelace
  YAML cover the same need without a frontend ecosystem in a Python repo.

Integration scope stays: sun curve + runtime entities + options flow.
2026-05-17 22:21:12 +02:00
Casey
b8497b500f Archive add-runtime-range-controls
47/47 tasks complete, including live verification on production HA:
- 4 number entities × 6 profiles registered (42 AL entities total)
- Slider drag does not reload integration (entry.modified_at stable)
- Curve picks up new slider value on next recompute
- Options flow seeds from entity state, not entry.options
- Save snaps sliders to typed values via reload
- RestoreNumber persists slider position across HA restart
- Friendly names now read as "<profile> Brightness" / "Color" / etc.

Delta synced into canonical specs:
- options-flow MR4 (curve bound values come from entities)
- runtime-range-controls capability added (7 requirements)

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-17 21:58:32 +02:00
Casey
d5d3ecc9d4 Implement add-runtime-range-controls
Adds four live-tunable `number` entities per AL profile (min/max
brightness, min/max color temp) that own the runtime curve values.
Slider changes take effect on the next curve tick — no integration
reload. State persists across HA restart via `RestoreNumber`.

Curve math now reads `min_brightness`, `max_brightness`,
`min_color_temp`, `max_color_temp` from the four runtime entities
via the entity registry, falling back to `entry.options` when an
entity is unavailable. The options flow seeds its four range fields
from the current entity state so the dialog matches reality.

Also fixes entity friendly names via HA's `has_entity_name`
composition: profile "Dining MVP" now reads as "Dining MVP",
"Dining MVP Brightness", "Dining MVP Color" — short enough for
HA's tightest cards. `unique_id`s are unchanged so existing
entity_ids stay stable.

Manifest bumped to 2.1.0-cdit.1 (minor, no breaking changes).
14 new tests in `tests/test_number_platform.py`; 108 passing
overall. OpenSpec change archived once 9.x live-HA verification
completes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-16 22:24:39 +02:00
Casey
c1a98a5c91 Archive cdit-config-redesign: 53/53 + repo description
Task 9.4: GitHub repo description and topics set via `gh repo edit`.
Description: "CDiT-opinionated fork of basnijholt/adaptive-lighting —
sectioned config, entity-driven sun timing (Sun2-friendly), synthetic
tanh curve. Not a drop-in replacement; star upstream too." Topics:
home-assistant, hacs, adaptive-lighting, circadian-lighting, cdit,
opinionated-fork, custom-component, home-automation.

Archive: change moved to openspec/changes/archive/2026-05-16-cdit-
config-redesign/. The 9 ADDED Requirements from the delta were synced
into openspec/specs/options-flow/spec.md as the canonical capability
spec — this is the first long-lived spec in the repo.

Result: cdit-config-redesign is 53/53 complete, archived, validated,
synced. The three remaining active changes (add-lovelace-card,
add-runtime-range-controls, house-mode-modes) sit in the roadmap.
2026-05-16 17:08:53 +02:00
Casey
a8b289240c 4.3 done: task complete + lessons from live HA deploy
Marked 4.3 (manual UI test of OptionsFlowWithReload reload-on-save +
entity-ID preservation) as complete after end-to-end verification on
the real HA install at homeassistant.onca-blenny.ts.net:

  - Created a fresh test profile via the new config flow
  - Confirmed 3 switches (master + adapt_color + adapt_brightness, no
    sleep) registered
  - Opened the options flow — 6 sections render in the order specified
    in spec R1
  - Toggled include_config_in_attributes off → on, saved
  - Entry stayed in `loaded` state, no restart prompt, all 3 entity
    IDs preserved across the reload
  - Field change landed on the master switch's attributes

Bonus: during the production run, also migrated all 6 existing AL
profiles from the upstream-shape entries (stuck in MIGRATION_ERROR
after our v1→v2 break) onto the new sectioned schema. 4/6 fully
migrated with their snapshotted config; 2/6 (dining_mvp,
ko_circadian_lights) saved with the lights that ARE currently
registered — `light.liv_lt_lights` and `light.hll_lt_main` are not
present in HA right now (offline or renamed).

The only task left in this change is 9.4 (gh repo description /
topics), which is a one-liner outside the code base.
2026-05-16 16:29:28 +02:00
Casey
e09d2a19fb Untrack .ha_snapshot_pre_cdit.json (user's HA config snapshot, gitignored) 2026-05-16 16:23:36 +02:00
Casey
249d18689e Fix OptionsFlowWithReload incompatibility with add_update_listener
Production HA caught this on the first save attempt: HA rejects
`config_entry.add_update_listener()` when the integration also uses
`OptionsFlowWithReload`, raising:

    ValueError: Config entry update listeners should not be used with
    OptionsFlowWithReload

The listener was a vestigial bit of the pre-redesign reload plumbing
that should have been deleted alongside the manual reload path (design
decision D6). Removed:

- `config_entry.add_update_listener(async_update_options)` registration
  in `async_setup_entry`
- `async_update_options` helper (only existed to call `async_reload`)
- `UNDO_UPDATE_LISTENER` tracking in `async_unload_entry`
- The `UNDO_UPDATE_LISTENER` import (still defined in const.py for any
  external code that imports it; pruning that is a separate cleanup)

Updated `tests/test_init.py::test_successful_setup_on_current_version`
to assert `entry.entry_id in hass.data[DOMAIN]` instead of the listener
key. All 94 tests still pass locally.

This is the first real-HA-only bug we've shipped — props to the
production deploy for catching it before merge.
2026-05-16 16:23:23 +02:00
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