Skip to content

Adaptive Cover Pro ⛅ v2026.8.1

Choose a tag to compare

@jrhubott jrhubott released this 08 Aug 00:34
· 13 commits to main since this release

Highlights

2026.8.1 is an in-month patch — five bug fixes back-ported from develop, no new features, no configuration changes and nothing to migrate. Two of them are behaviour fixes worth calling out: venetian tilt-only covers no longer hold their last daytime slat angle all night when a non-solar handler wins the pipeline (#1214), and the climate decision trace no longer stamps a season label on a decision that no season strategy produced (#1196) — which also unsticks the sunset force-send, the dual-panel heat blackout, and the day/night blackout fabric in that path. The other three are release-tooling and config-UI fixes: the Change Cover Type picker now offers and preselects the type you're already on, and the release script no longer leaks a log line into the published release notes.

Fixed

  • Default-position handlers get their own sunset tilt (#1214, #1218): #1153 correctly dropped tilt from the pipeline registry's _MERGEABLE set so a losing DefaultHandler could no longer leak default_tilt onto a winning handler. But three handlers answer with compute_default_position() and label themselves ControlMethod.DEFAULT without ever supplying a tilt of their own, so sunset_tilt and default_tilt became unreachable whenever one of them won — venetian tilt-only covers held their last daytime slat angle all night.

    I extracted the resolution out of DefaultHandler into pipeline.helpers.compute_default_tilt(), preserving sunset precedence, the default_tilt fallback, the #503 clamp on the non-sunset branch and the #128 unclamped sunset carve-out. ClimateHandler (LOW_LIGHT / TRACKING_SEASON_GATE), CloudSuppressionHandler, and MotionTimeoutHandler's return-to-default branch now each state their own tilt. MotionTimeoutHandler's hold branch stays untilted — a hold must hold. _MERGEABLE is untouched, so #1153's seam stays closed. I also refreshed the Default/Sunset Tilt copy across EN/DE/FR.

  • Climate labels follow the strategy, not the thermometer (#1196, #1209): ClimateHandler.evaluate() picked control_method from the is_summer/is_winter temperature predicates before consulting climate_strategy, so any non-season strategy reaching the label chain got stamped with a season label. A LOW_LIGHT fall-through to the default position reported SUMMER, and tilt GLARE_CONTROL reported SUMMER/WINTER even with the sun in the field of view.

    I gated the two season arms on a new _SEASON_STRATEGIES frozenset, so the season predicates are trusted only when a season strategy actually produced the position. LOW_LIGHT now reports DEFAULT and GLARE_CONTROL reports SOLAR in every season. This also corrects real downstream behaviour: on a LOW_LIGHT fall-through the sunset force-send is no longer suppressed, dual_panel no longer deploys the heat blackout, day_night_shade no longer forces the blackout fabric, and a tilt-only venetian carriage is no longer pinned.

  • Change Cover Type picker offers the current type, and DE/FR labels agree with the confirm screen (#1200, #1201, #1202, #1204): The picker filtered out the entry's own type and set no default, so Home Assistant highlighted whatever happened to be first. On a vertical blind that was the awning entry — whose English label also read "Horizontal blind" while the confirm screen called the same value "Horizontal Awning".

    I fixed the label, added the current type to the offered list with the suggested value pointing at it, and made picking it return to the menu instead of walking a no-op switch into the geometry step. Reverting a pending switch now gets its own confirm screen, so it no longer reads as "Vertical Blind to Vertical Blind". A new parity test locks every type the picker can offer to a label in all three languages.

  • scripts/release no longer leaks a log line into the published release body (#1187, #1207): get_release_notes() is captured via $(...), so its stdout is its return value. log_info wrote to stdout, which put an "ℹ Using release notes from: …" line at the top of the published GitHub release body. I gave log_info, log_success, log_warning, log_step and log_dry_run the same >&2 redirect log_error already had, so the whole helper family is safe inside a stdout-captured function rather than just the one call site that leaked. I also wrapped the main "$@" entry point in a BASH_SOURCE guard so the script can be sourced by a test without kicking off a real release. This release is the first one published with that fix active.

  • release-issue-lifecycle honours triage-exempt (#1188, #1205): The release lifecycle workflow tagged every referenced open issue released and then closed it in the sweep, with no way to exempt one — a commit only had to mention an issue number for that issue to be closed as fixed at the next stable cut. It bit twice during the v2026.8.0 release: #1173, whose only referencing commit rewrote xfail reasons and changed no behaviour, and #943, which carried reopened because the beta.1 work didn't cover the whole request.

    I added a triage-exempt guard to both mutation paths. In tagReferencedIssue() it goes first, before the awaiting-release/reopened stripping, so an exempt issue is left entirely untouched rather than partially mutated. The sweep needs its own gate because it queries GitHub by label.

📖 Documentation

  • Bug report form asks for less (#1200): I cut the required fields on the GitHub bug report form so filing an issue is less of a wall.

Testing

12,563 tests passing.

Compatibility

Home Assistant 2026.3.0+ and Python 3.11+. No migration runs for this release. The companion Lovelace card (jrhubott/adaptive-cover-pro-card) is a separate repo with its own release cycle.