Skip to content

Adaptive Cover Pro ⛅ v2.28.0-beta.3

Pre-release
Pre-release

Choose a tag to compare

@jrhubott jrhubott released this 10 Jun 18:52
· 171 commits to main since this release

ℹ Using release notes from: release_notes/v2.28.0-beta.3.md
This beta builds on beta.2 (FOV-mode selector, Measurements-mode config-flow save, imperial shaded-area compounding fix) by landing four targeted fixes: the FOV-mode selection now persists correctly on re-render so the save loop is gone, small 1–3% solar tracking moves are no longer swallowed by the same-position gate, set-position covers can reach true 0% during solar tracking, and string entity_id targets in services resolve correctly regardless of case or spacing.

🎯 Highlights

Beta — please test and report back.

  • Configure a window using MEASUREMENTS mode and confirm the mode sticks — previous betas had a save loop where the mode selection didn't persist on re-render. This is now fixed.
  • Verify small solar tracking adjustments (1–3%) are sent to the cover. beta.2 silently swallowed these moves; they should now go through.
  • If you have a set-position cover with a geometry path that previously stopped short of fully closed, confirm it reaches 0% during solar tracking.
  • Try the FOV-mode selector end-to-end: switch between ANGLES and MEASUREMENTS mode, save, reload, and confirm the saved mode is the one that loads.
  • Verify service calls that pass a string entity_id target resolve correctly, especially for sunset/sunrise time entity services.

✨ Features

Set-position covers can reach true 0% in solar tracking (#569, #572)

Adds a solar_floor() helper and a position_axis_supported() method on CoverTypePolicy to distinguish covers with the SET_POSITION capability from those limited to open/close/stop/tilt. Covers that support arbitrary position commands can now close fully (true 0%) during solar tracking. Previously, a geometry oversight in some paths prevented these covers from reaching 0%, leaving them stopped short of fully closed.

🐛 Bug Fixes

FOV mode not persisted on re-render causes save loop (#565)

When a FOV-mode switch triggered a re-render in ConfigFlowHandler or OptionsFlowHandler, the selected mode was passed to _show_sun_tracking_form but not written back into self.config or self.options. The form re-rendered with the old stored mode, which differed from the displayed mode, causing an infinite re-render cycle. The fix writes CONF_FOV_MODE into the config/options dict before calling _show_sun_tracking_form, so the persisted value and the displayed value stay in sync. Covered by test_create_flow_switch_to_measurements_then_save, test_imperial_switch_to_measurements_then_save, and test_switching_to_measurements_then_submitting_saves.

Same-position gate used tolerance band, swallowing 1–3% tracking moves (#567, #574)

A position tolerance band introduced in #567 widened the same-position gate so that positions within the tolerance range were treated as identical and not sent. This silently dropped small solar tracking adjustments. The fix reverts the same-position gate to exact equality; movement hysteresis is preserved in the reconcile path, which is the right place for it. Covered by test_apply_position_one_percent_tracking_move_is_sent, test_same_position_band_uses_exact_equality_not_tolerance, test_unreachable_target_suppressed_by_reconcile_not_command_gate, and test_reconcile_gives_up_on_unreachable_target.

String entity_id in service targets not normalizing correctly (#570, #571)

Services that accept a string entity_id target now normalize the value before resolution, so case or spacing variations no longer cause silent failures. Adds regression test coverage via TestStringEntityIdRegression, and adds coverage for the sunset/sunrise time entity service paths via TestSunsetSunriseTimeEntity, including test_set_option_sunset_time_entity_accepted and test_set_option_sunrise_time_entity_accepted.

Previously in this beta line

Measurements mode config-flow save and imperial shaded-area compounding (beta.2, #565): The FOV sliders were emitted as vol.Required markers, blocking the frontend from switching to Measurements mode. A _as_optional() helper re-emits them as vol.Optional to unblock the mode switch. Imperial shaded-area values also compounded on each re-render because user_input was fed back into _show_sun_tracking_form without first converting it back to canonical metres; the fix calls user_input_to_canonical() once up front.

Low-sun edge case returns closed position (beta.1, #559, #562): At very low sun elevations, a geometry edge case returned h_win (fully open) instead of 0 (fully closed). The cover now closes when the sun is near the horizon.

🔧 Internal

Write-gating, geometry caching, and sun availability guard (#543)

Shipped in beta.1, carried here for completeness:

  • Write-gating: _acp_render_signature() detects when a calculated position matches the last written value and skips the HA state write, reducing redundant entity updates.
  • Geometry cache: Pure geometry helpers decorated with @lru_cache(maxsize=512) eliminate repeated identical calculations across update cycles.
  • Sun availability guard: A guard on sun.sun suppresses solar tracking when the sun entity is unavailable, preventing stale or error-state data from driving cover commands.

🧪 Testing

4,316 tests passing (up from ~4,276 at beta.2).

Compatibility

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

References