Skip to content

Adaptive Cover Pro ⛅ v2.28.0-beta.13

Pre-release
Pre-release

Choose a tag to compare

@jrhubott jrhubott released this 16 Jun 22:05
· 111 commits to main since this release

ℹ Using release notes from: release_notes/v2.28.0-beta.13.md
Beta.13 brings two solar geometry improvements: a full vertical-drop shade model for the oscillating awning that replaces the old horizontal-reach approximation, and anticipatory solar positioning that commands the most protective cover angle across the entire throttle window rather than just the sun's current location.

🎯 Highlights

Beta — please test and report back.

  • If you have an oscillating or drop awning, test at low sun elevations (morning/late afternoon, sun near the horizon). The cover should extend further to keep the window shaded — the new model solves actual lip-shadow geometry against the window bottom, so protection should improve noticeably at shallow sun angles where the old reach approximation fell short.
  • At high sun elevations, confirm the awning does not over-extend — the arc scan finds the smallest angle that reaches the protected boundary, so it should stay conservative when elevation is steep.
  • For solar anticipation, set a larger CONF_DELTA_TIME (e.g. 10–15 minutes) and watch a tracking cover during a period of fast sun movement. The cover should move to a position that stays protective through the end of the throttle window, not just at the moment of the command.
  • Confirm that covers with a 2-minute CONF_DELTA_TIME (the default minimum) still track normally — the anticipation window is narrow at the minimum and should behave identically to the previous logic.
  • Verify the decision trace reflects the anticipated position, not the raw current-sun position, when anticipation changes the commanded value.

✨ Features

Vertical-drop shade model for the oscillating awning (#586)

The oscillating awning previously estimated shade coverage using only the awning's horizontal reach — a projection that degrades at low sun elevations, where the awning's lip casts a shadow whose top edge rises well above the window bottom. At shallow angles the cover either over-extended to compensate or left the window unprotected.

The new model in engine/covers/oscillating.py solves this geometrically. _foreshortened_drop_per_reach computes the ray-foreshortened vertical drop per unit of arm reach as a function of solar elevation and the angle between the sun and the awning normal (gamma). _lip_shadow_top uses that ratio to find where the shadow's top edge lands on the window face for a given arm angle. _protected_boundary wires the result into the inherited vertical solve. At startup, the handler scans the full arm-sweep arc in OSCILLATING_ARC_SCAN_SAMPLES steps and returns the smallest arm angle whose shadow top meets or clears the protected boundary — OSCILLATING_PROTECTED_BOUNDARY_DEFAULT (0.0 m, the window bottom) by default.

Two new constants in const.py: OSCILLATING_PROTECTED_BOUNDARY_DEFAULT sets the reference height, and OSCILLATING_ARC_SCAN_SAMPLES (1801) controls scan resolution.

Anticipatory solar positioning across the throttle window (#616)

Because covers can only move once per CONF_DELTA_TIME, commanding the sun's current protective position can leave the cover under-protected before the next allowed move — the sun keeps moving, but the cover cannot follow until the throttle expires. The solar handler now samples several future sun positions across the interval (now, now + CONF_DELTA_TIME] and commands the most protective one, so coverage holds through the entire window.

The new helper anticipated_solar_position in pipeline/helpers.py drives the sampling loop. It folds each sampled position through more_protective_position, a new polymorphic comparator on the cover-type policy base (cover_types/base.py) that returns whichever of two positions is more protective for that cover type — lower percentage for blinds, with awnings overriding the direction. SolarHandler in pipeline/handlers/solar.py calls anticipated_solar_position in place of the plain current-position computation.

The number of samples is SOLAR_ANTICIPATION_SAMPLES (4, kept small because SunData is 5-minute resolution). A new snapshot field time_threshold_minutes in pipeline/types.py and pipeline/snapshot_builder.py threads the delta-time horizon into the snapshot so the helper can read it without touching coordinator state directly.

Previously in this beta line

  • Position matching preserved for covers upgraded from earlier in the beta line, held position surfaced in the manual-override decision trace (beta.12, #591, #606, #608)
  • Custom-position sensor migration gate fixed (beta.11, #563, #607)
  • Solar-tracking position forecast in diagnostics, vertical extreme-gamma/high-elevation edge cases removed, legacy custom-position sensor migration added (beta.10, #563, #597, #598, #599, #600, #601)
  • FOV generate-from-measurements button replaces two-mode selector, position matching opt-in with disable-retry option, climate status sensor always exposes threshold setpoints and typed inactive_reason slugs, FOV preview shown at depth 0 (beta.9, #565, #589, #590, #591, #592, #595, #596)
  • Measurements-mode FOV sliders visible with editable suggested value, config summary shows [template] for Jinja2 threshold values (beta.8, #565, #577, #587, #588)
  • Force Override merged into Custom Positions, FOV formula corrected (beta.7, #563, #565, #584, #583)
  • Jinja2 templates in threshold fields and optional occupancy template (beta.6, #577, #578)
  • Configuration Summary translated to user's language (beta.4/beta.5, #258, #575, #576)
  • Set-position covers can reach true 0% in solar tracking (beta.3/beta.4, #569, #572)
  • Same-position gate reverted to exact equality, restoring 1–3% tracking moves (beta.3, #567, #574)
  • String entity_id in service targets now normalizes correctly (beta.3, #570, #571)
  • FOV mode persisted on re-render, fixing save loop (beta.2/beta.3, #565)
  • Measurements-mode config-flow save and imperial shaded-area compounding fixes (beta.2, #565)
  • Low-sun edge case returns closed position (beta.1, #559, #562)
  • Write-gating, geometry caching, and sun availability guard (beta.1, #543)

Compatibility

Requires Home Assistant 2026.3.0+. No new coupled-component requirements.

References