Skip to content

Adaptive Cover Pro ⛅ v2.28.0-beta.4

Pre-release
Pre-release

Choose a tag to compare

@jrhubott jrhubott released this 11 Jun 04:23
· 166 commits to main since this release

ℹ Using release notes from: release_notes/v2.28.0-beta.4.md
This beta builds on beta.3 (FOV-mode persistence fix, same-position gate exact equality, set-position covers reaching true 0%, string entity_id normalization) by completing the Configuration Summary translation work from issue #258: the narrative summary shown in the config/options flow now renders in the user's Home Assistant language, with German and French shipping alongside English as the source.

🎯 Highlights

Beta — please test and report back.

  • German/French users: switch your HA language and open the config or options flow for any cover. Confirm the Configuration Summary renders in your language — priority rules, position limits, warnings, headers, the cover-type label, and dimension lines should all appear translated.
  • Confirm the English fallback works: if a translation key is missing (e.g. a custom HA locale), the summary should fall back to English rather than showing a blank or an error.
  • 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

Configuration Summary translated to user's language (#258, #575, #576)

The narrative Configuration Summary shown in the config/options flow is now fully translated. This landed in two steps:

Translate configuration summary to user's language (#258, #575): Adds a config_summary top-level translation namespace in en.json with templated leaves (banner, headers, cover, words, fragments, rules, etc.) — each leaf is a Python str.format template with {field} placeholders. _load_summary_labels(hass, language) loads the translated label set via HA's translation system (category config_summary); _config_summary_flat(data) flattens the nested namespace into dotted keys. A no-hass / missing-key English fallback keeps the summary rendering without translations. German and French ship alongside English.

Translate cover-type label and dimension block (#258, #576): The cover-type label (e.g. "Vertical Blind", "Horizontal Awning", "Venetian / Tilt Blind") and the window/geometry dimension lines in the summary are also translated. Adds cover_types and geometry namespaces under config_summary in en.json. A display_label(labels) method on the CoverTypePolicy subclasses returns the translated cover-type name with an English fallback; summary_geometry_lines(config) returns the translated dimension lines per cover type.

Both features ship English/German/French. Verified identifiers: _load_summary_labels, _config_summary_flat, _load_json, _placeholder_fields, _walk, display_label, summary_geometry_lines, _cover_type_label, window_dimensions_lines, computed_fov_line, _flatten, _en_config_summary.

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,327 tests passing (up from 4,316 at beta.3).

Compatibility

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

References