Releases: jrhubott/adaptive-cover-pro
Release list
Adaptive Cover Pro ⛅ v2026.8.4-alpha.202608211315
🛠️ Develop build from
develop— unstable, for testing.
Auto-generated from the latest development code. Expect rough edges — not for production use.
Hit a problem? Open an issue and include this develop build version string.
What's Changed
- feat: show custom slot names in the config summary rules (#1190) by @jrhubott in #1193
- feat: serialize commands across covers via a named queue by @jrhubott in #1194
- fix: picker offers the current cover type; DE/FR label parity by @jrhubott in #1202
- fix: honour triage-exempt in release-issue-lifecycle (#1188) by @jrhubott in #1205
- fix: keep scripts/release log output out of the published release body (#1187) by @jrhubott in #1207
- fix: trust the strategy, not the thermometer, for climate labels (#1196) by @jrhubott in #1209
- fix: DE/FR cover-type wording slips (#1203) by @jrhubott in #1212
- fix: judge a coupled hold against its own position (#1179) by @jrhubott in #1213
- fix: keep tilt bounds on a tilt-only slot with no fixed tilt (#1215) by @jrhubott in #1217
- fix: give default-position handlers their own sunset tilt (#1214) by @jrhubott in #1218
- fix: Target Position follows the dispatched target when a bound clamps a hold (#1175) by @jrhubott in #1221
- fix: retire the sign-inverted vertical safety margin (#1173) by @jrhubott in #1224
- fix: give is_safety a defined lifetime across skips and resends (#1165) by @jrhubott in #1226
- feat: three-point tilt calibration for asymmetric Venetian slat travel (#1222) by @jrhubott in #1228
- fix: normalise inverse-tilt wire publish in venetian manual-override delta by @slangeder in #1227
- feat: sensor-gated constraints that act outside the time window (#943) by @jrhubott in #1229
- fix: stop an unset manual-override toggle wiping restored state (#1232) by @jrhubott in #1245
- fix: inherit drift-reset ineligibility on the tilt retry (#1234) by @jrhubott in #1246
- fix: expose sun-tracking min position in set_position_limits (#1242) by @jrhubott in #1252
- feat: guard the forward-merge and stale-checkout releases by @jrhubott in #1250
- docs: drop the HANDOFF read from live-diagnose startup by @jrhubott in #1255
- fix: refresh pipeline before the end-time override guard (#1241) by @jrhubott in #1257
- fix: anchor a blank start time to sunrise, not midnight (#1256) by @jrhubott in #1259
- fix: measure occupancy timeout expiry from timer start (#1266) by @jrhubott in #1268
- fix: gate climate low-light on the cloud-suppression hold (#1238) by @jrhubott in #1262
- feat: offer the companion card install in the options flow by @jrhubott in #1261
- fix: let cleared optional config fields round-trip (#1267) by @jrhubott in #1270
- fix: agree both manual-override axes on the threshold boundary (#1273) by @jrhubott in #1275
- fix: keep wait-for-target while a command is unreacted (#1139) by @jrhubott in #1276
- feat: add cover solar properties and an estimated solar gain sensor by @jrhubott in #1279
- fix: refuse to estimate solar gain from a non-W/m2 irradiance sensor by @jrhubott in #1281
- fix: clear the no-motion timer stamp when it expires (#1266) by @jrhubott in #1288
- fix: key the sunset edge on the configured boundary (#1287) by @jrhubott in #1289
- fix: make the vertical sill offset perpendicular (#1290) by @jrhubott in #1293
- fix: publish blind-spot gamma keys in diagnostics config by @jrhubott in #1295
- feat: publish per-slot blind-spot elevation gating (#1292) by @jrhubott in #1294
- fix: negate the cloud suppression weather condition (#1301) by @jrhubott in #1303
- feat: defer cloud suppression during the extreme-heat hold (#1272) by @jrhubott in #1305
- feat: scope the weather override to the time window (#1308) by @jrhubott in #1309
- fix: treat a post-ack settle without progress as a reversal (#1306) by @litithio in #1239
- fix: revoke stale is_safety on the closed-clock cycle (#1311) by @jrhubott in #1312
- fix: correct the cloud-suppression summary and outside-window explanation by @jrhubott in #1314
- fix: revoke stale licences on force-send's closed-clock exit (#1313) by @jrhubott in #1316
- fix: revoke stale is_safety on an external stop's My booking (#1225) by @jrhubott in #1315
- feat: add a weather-override tilt for venetian blinds (#1297) by @jrhubott in #1317
New Contributors
- @slangeder made their first contribution in #1227
- @litithio made their first contribution in #1239
Full Changelog: v2026.8.3...v2026.8.4-alpha.202608211315
Adaptive Cover Pro ⛅ v2026.8.4-alpha.202608201343
🛠️ Develop build from
develop— unstable, for testing.
Auto-generated from the latest development code. Expect rough edges — not for production use.
Hit a problem? Open an issue and include this develop build version string.
What's Changed
- feat: show custom slot names in the config summary rules (#1190) by @jrhubott in #1193
- feat: serialize commands across covers via a named queue by @jrhubott in #1194
- fix: picker offers the current cover type; DE/FR label parity by @jrhubott in #1202
- fix: honour triage-exempt in release-issue-lifecycle (#1188) by @jrhubott in #1205
- fix: keep scripts/release log output out of the published release body (#1187) by @jrhubott in #1207
- fix: trust the strategy, not the thermometer, for climate labels (#1196) by @jrhubott in #1209
- fix: DE/FR cover-type wording slips (#1203) by @jrhubott in #1212
- fix: judge a coupled hold against its own position (#1179) by @jrhubott in #1213
- fix: keep tilt bounds on a tilt-only slot with no fixed tilt (#1215) by @jrhubott in #1217
- fix: give default-position handlers their own sunset tilt (#1214) by @jrhubott in #1218
- fix: Target Position follows the dispatched target when a bound clamps a hold (#1175) by @jrhubott in #1221
- fix: retire the sign-inverted vertical safety margin (#1173) by @jrhubott in #1224
- fix: give is_safety a defined lifetime across skips and resends (#1165) by @jrhubott in #1226
- feat: three-point tilt calibration for asymmetric Venetian slat travel (#1222) by @jrhubott in #1228
- fix: normalise inverse-tilt wire publish in venetian manual-override delta by @slangeder in #1227
- feat: sensor-gated constraints that act outside the time window (#943) by @jrhubott in #1229
- fix: stop an unset manual-override toggle wiping restored state (#1232) by @jrhubott in #1245
- fix: inherit drift-reset ineligibility on the tilt retry (#1234) by @jrhubott in #1246
- fix: expose sun-tracking min position in set_position_limits (#1242) by @jrhubott in #1252
- feat: guard the forward-merge and stale-checkout releases by @jrhubott in #1250
- docs: drop the HANDOFF read from live-diagnose startup by @jrhubott in #1255
- fix: refresh pipeline before the end-time override guard (#1241) by @jrhubott in #1257
- fix: anchor a blank start time to sunrise, not midnight (#1256) by @jrhubott in #1259
- fix: measure occupancy timeout expiry from timer start (#1266) by @jrhubott in #1268
- fix: gate climate low-light on the cloud-suppression hold (#1238) by @jrhubott in #1262
- feat: offer the companion card install in the options flow by @jrhubott in #1261
- fix: let cleared optional config fields round-trip (#1267) by @jrhubott in #1270
- fix: agree both manual-override axes on the threshold boundary (#1273) by @jrhubott in #1275
- fix: keep wait-for-target while a command is unreacted (#1139) by @jrhubott in #1276
- feat: add cover solar properties and an estimated solar gain sensor by @jrhubott in #1279
- fix: refuse to estimate solar gain from a non-W/m2 irradiance sensor by @jrhubott in #1281
- fix: clear the no-motion timer stamp when it expires (#1266) by @jrhubott in #1288
- fix: key the sunset edge on the configured boundary (#1287) by @jrhubott in #1289
- fix: make the vertical sill offset perpendicular (#1290) by @jrhubott in #1293
- fix: publish blind-spot gamma keys in diagnostics config by @jrhubott in #1295
- feat: publish per-slot blind-spot elevation gating (#1292) by @jrhubott in #1294
- fix: negate the cloud suppression weather condition (#1301) by @jrhubott in #1303
- feat: defer cloud suppression during the extreme-heat hold (#1272) by @jrhubott in #1305
- feat: scope the weather override to the time window (#1308) by @jrhubott in #1309
- fix: treat a post-ack settle without progress as a reversal (#1306) by @litithio in #1239
- fix: revoke stale is_safety on the closed-clock cycle (#1311) by @jrhubott in #1312
- fix: correct the cloud-suppression summary and outside-window explanation by @jrhubott in #1314
- fix: revoke stale licences on force-send's closed-clock exit (#1313) by @jrhubott in #1316
- fix: revoke stale is_safety on an external stop's My booking (#1225) by @jrhubott in #1315
New Contributors
- @slangeder made their first contribution in #1227
- @litithio made their first contribution in #1239
Full Changelog: v2026.8.3...v2026.8.4-alpha.202608201343
Adaptive Cover Pro ⛅ v2026.8.4-alpha.202608200537
🛠️ Develop build from
develop— unstable, for testing.
Auto-generated from the latest development code. Expect rough edges — not for production use.
Hit a problem? Open an issue and include this develop build version string.
What's Changed
- feat: show custom slot names in the config summary rules (#1190) by @jrhubott in #1193
- feat: serialize commands across covers via a named queue by @jrhubott in #1194
- fix: picker offers the current cover type; DE/FR label parity by @jrhubott in #1202
- fix: honour triage-exempt in release-issue-lifecycle (#1188) by @jrhubott in #1205
- fix: keep scripts/release log output out of the published release body (#1187) by @jrhubott in #1207
- fix: trust the strategy, not the thermometer, for climate labels (#1196) by @jrhubott in #1209
- fix: DE/FR cover-type wording slips (#1203) by @jrhubott in #1212
- fix: judge a coupled hold against its own position (#1179) by @jrhubott in #1213
- fix: keep tilt bounds on a tilt-only slot with no fixed tilt (#1215) by @jrhubott in #1217
- fix: give default-position handlers their own sunset tilt (#1214) by @jrhubott in #1218
- fix: Target Position follows the dispatched target when a bound clamps a hold (#1175) by @jrhubott in #1221
- fix: retire the sign-inverted vertical safety margin (#1173) by @jrhubott in #1224
- fix: give is_safety a defined lifetime across skips and resends (#1165) by @jrhubott in #1226
- feat: three-point tilt calibration for asymmetric Venetian slat travel (#1222) by @jrhubott in #1228
- fix: normalise inverse-tilt wire publish in venetian manual-override delta by @slangeder in #1227
- feat: sensor-gated constraints that act outside the time window (#943) by @jrhubott in #1229
- fix: stop an unset manual-override toggle wiping restored state (#1232) by @jrhubott in #1245
- fix: inherit drift-reset ineligibility on the tilt retry (#1234) by @jrhubott in #1246
- fix: expose sun-tracking min position in set_position_limits (#1242) by @jrhubott in #1252
- feat: guard the forward-merge and stale-checkout releases by @jrhubott in #1250
- docs: drop the HANDOFF read from live-diagnose startup by @jrhubott in #1255
- fix: refresh pipeline before the end-time override guard (#1241) by @jrhubott in #1257
- fix: anchor a blank start time to sunrise, not midnight (#1256) by @jrhubott in #1259
- fix: measure occupancy timeout expiry from timer start (#1266) by @jrhubott in #1268
- fix: gate climate low-light on the cloud-suppression hold (#1238) by @jrhubott in #1262
- feat: offer the companion card install in the options flow by @jrhubott in #1261
- fix: let cleared optional config fields round-trip (#1267) by @jrhubott in #1270
- fix: agree both manual-override axes on the threshold boundary (#1273) by @jrhubott in #1275
- fix: keep wait-for-target while a command is unreacted (#1139) by @jrhubott in #1276
- feat: add cover solar properties and an estimated solar gain sensor by @jrhubott in #1279
- fix: refuse to estimate solar gain from a non-W/m2 irradiance sensor by @jrhubott in #1281
- fix: clear the no-motion timer stamp when it expires (#1266) by @jrhubott in #1288
- fix: key the sunset edge on the configured boundary (#1287) by @jrhubott in #1289
- fix: make the vertical sill offset perpendicular (#1290) by @jrhubott in #1293
- fix: publish blind-spot gamma keys in diagnostics config by @jrhubott in #1295
- feat: publish per-slot blind-spot elevation gating (#1292) by @jrhubott in #1294
- fix: negate the cloud suppression weather condition (#1301) by @jrhubott in #1303
- feat: defer cloud suppression during the extreme-heat hold (#1272) by @jrhubott in #1305
- feat: scope the weather override to the time window (#1308) by @jrhubott in #1309
- fix: treat a post-ack settle without progress as a reversal (#1306) by @litithio in #1239
- fix: revoke stale is_safety on the closed-clock cycle (#1311) by @jrhubott in #1312
New Contributors
- @slangeder made their first contribution in #1227
- @litithio made their first contribution in #1239
Full Changelog: v2026.8.3...v2026.8.4-alpha.202608200537
Adaptive Cover Pro ⛅ v2026.8.4-alpha.202608200335
🛠️ Develop build from
develop— unstable, for testing.
Auto-generated from the latest development code. Expect rough edges — not for production use.
Hit a problem? Open an issue and include this develop build version string.
What's Changed
- feat: show custom slot names in the config summary rules (#1190) by @jrhubott in #1193
- feat: serialize commands across covers via a named queue by @jrhubott in #1194
- fix: picker offers the current cover type; DE/FR label parity by @jrhubott in #1202
- fix: honour triage-exempt in release-issue-lifecycle (#1188) by @jrhubott in #1205
- fix: keep scripts/release log output out of the published release body (#1187) by @jrhubott in #1207
- fix: trust the strategy, not the thermometer, for climate labels (#1196) by @jrhubott in #1209
- fix: DE/FR cover-type wording slips (#1203) by @jrhubott in #1212
- fix: judge a coupled hold against its own position (#1179) by @jrhubott in #1213
- fix: keep tilt bounds on a tilt-only slot with no fixed tilt (#1215) by @jrhubott in #1217
- fix: give default-position handlers their own sunset tilt (#1214) by @jrhubott in #1218
- fix: Target Position follows the dispatched target when a bound clamps a hold (#1175) by @jrhubott in #1221
- fix: retire the sign-inverted vertical safety margin (#1173) by @jrhubott in #1224
- fix: give is_safety a defined lifetime across skips and resends (#1165) by @jrhubott in #1226
- feat: three-point tilt calibration for asymmetric Venetian slat travel (#1222) by @jrhubott in #1228
- fix: normalise inverse-tilt wire publish in venetian manual-override delta by @slangeder in #1227
- feat: sensor-gated constraints that act outside the time window (#943) by @jrhubott in #1229
- fix: stop an unset manual-override toggle wiping restored state (#1232) by @jrhubott in #1245
- fix: inherit drift-reset ineligibility on the tilt retry (#1234) by @jrhubott in #1246
- fix: expose sun-tracking min position in set_position_limits (#1242) by @jrhubott in #1252
- feat: guard the forward-merge and stale-checkout releases by @jrhubott in #1250
- docs: drop the HANDOFF read from live-diagnose startup by @jrhubott in #1255
- fix: refresh pipeline before the end-time override guard (#1241) by @jrhubott in #1257
- fix: anchor a blank start time to sunrise, not midnight (#1256) by @jrhubott in #1259
- fix: measure occupancy timeout expiry from timer start (#1266) by @jrhubott in #1268
- fix: gate climate low-light on the cloud-suppression hold (#1238) by @jrhubott in #1262
- feat: offer the companion card install in the options flow by @jrhubott in #1261
- fix: let cleared optional config fields round-trip (#1267) by @jrhubott in #1270
- fix: agree both manual-override axes on the threshold boundary (#1273) by @jrhubott in #1275
- fix: keep wait-for-target while a command is unreacted (#1139) by @jrhubott in #1276
- feat: add cover solar properties and an estimated solar gain sensor by @jrhubott in #1279
- fix: refuse to estimate solar gain from a non-W/m2 irradiance sensor by @jrhubott in #1281
- fix: clear the no-motion timer stamp when it expires (#1266) by @jrhubott in #1288
- fix: key the sunset edge on the configured boundary (#1287) by @jrhubott in #1289
- fix: make the vertical sill offset perpendicular (#1290) by @jrhubott in #1293
- fix: publish blind-spot gamma keys in diagnostics config by @jrhubott in #1295
- feat: publish per-slot blind-spot elevation gating (#1292) by @jrhubott in #1294
- fix: negate the cloud suppression weather condition (#1301) by @jrhubott in #1303
- feat: defer cloud suppression during the extreme-heat hold (#1272) by @jrhubott in #1305
- feat: scope the weather override to the time window (#1308) by @jrhubott in #1309
- fix: treat a post-ack settle without progress as a reversal (#1306) by @litithio in #1239
New Contributors
- @slangeder made their first contribution in #1227
- @litithio made their first contribution in #1239
Full Changelog: v2026.8.3...v2026.8.4-alpha.202608200335
Adaptive Cover Pro ⛅ v2026.8.3
Highlights
2026.8.3 is an in-month patch: four bug fixes back-ported from develop, no new features, no configuration changes and nothing to migrate. Two of them fix things the UI told users outright wrongly. The occupancy countdown no longer reads "expired" for its entire life, which is what made the occupancy sensors look inverted (#1266). The Configuration Summary's cloud-suppression line said "weather in {sunny, …}" when suppression actually fires when the weather is not in that set — the exact opposite of what every install was configured to do, in all three shipped languages (#1301). The other two restore a blind spot's sky-compass wedge, which has published nothing at all on current stable (#1291), and let cleared optional config fields actually stay cleared (#1267).
Fixed
-
The occupancy timeout end time is measured from the timer, not the last detection (#1266):
_motion_status_attrsderivedmotion_timeout_end_timefromlast_motion_time— the occupancy detection stamp — plus the timeout, but the no-motion timer starts on the clear edge. Anyone present for longer than the configured timeout pushed the published end time into the past the instant the timer actually started, so the card rendered "expires in expired" for the whole live countdown. With the default 300 second timeout, five minutes of continuous presence was enough.MotionManagernow stamps_timeout_started_atwhen the timer starts and owns the formula behind atimeout_end_timeproperty; the sensor publishes that verbatim and drops its private_timeout_secondsreach. The second half of the defect was the state after the countdown ends:_on_motion_timeout_expiredset_motion_timeout_activewithout clearing the stamp, so the property kept returning a past timestamp for the entire no-occupancy state. All four exits from "timer counting" —record_motion_detected,cancel_motion_timeout,set_no_motion, and the timer firing naturally — now clear it, so the property honors its documented contract: a time while the timer runs,Noneotherwise. The attribute name and payload shape are unchanged, and the companion card already renders nothing when the attribute is absent, so no card release is needed.This is most of why the issue was filed as an inversion. The remaining half is wording:
reason_i18n.pyprints "occupancy timeout active" beside "No Occupancy" and "occupancy timeout not active" beside "Occupancy Detected". Both statements are true about the internal flag and both read as the inverse of the occupancy state next to them. That is a separate change across all three translation bundles and is not fixed here. -
Cleared optional config fields round-trip (#1267): Emptying the Motion Template field in the options flow did not stick — the old template stayed in the config entry with no way to delete it from the UI.
optional_entities()fills inNonefor any key voluptuous dropped fromuser_input, and it has to run beforeoptions.update()for a clear to overwrite anything.async_step_motion_overridenever called it.Auditing the rest of the options flow for the same defect class turned up two more paths with no clearing call at all.
async_step_interpleftCONF_INTERP_START/CONF_INTERP_ENDset, so a custom interpolation range could not be removed once configured._render_blind_spot_slot'smappedcomprehension skips any key missing fromuser_input, silently dropping a clearedright_gamma(slots 2 and 3) orelevation(all slots). All three now reuse the existingoptional_entities()helper, inserted after each step's validation early-return so a rejected form clears nothing.left_gammacarries a schema default in every slot and is excluded on purpose. -
Blind spots publish their gamma range again (#1291): The per-slot sub-key tuple in
DiagnosticsBuilder._build_configurationcopied onlyleft,right,elevationandelevation_modeinto the diagnosticsconfigurationdict, soleft_gamma/right_gammanever reached it. The sun sensor's gamma-preferred branch in_sun_position_attrswas therefore dead on that path, and because the options flow has written gamma keys only since v3.8, the legacy fallback found nothing either. Every configured blind spot published noblind_spot_rangeand noblind_spot_rangesat all — while the engine, which reads raw entry options, kept computing the correct position. That is why the card's sky compass showed no wedge while the blind sat exactly where it should.This is live on 2026.8.2: it carries both the four-key tuple and the gamma-only form keys, so any blind spot configured on current stable publishes nothing. Widening the tuple activates the already-correct gamma branch; no sensor change and no card change are needed. Entries migrated from before v3.8 hold both key sets, so gamma now wins over legacy in the published attribute, matching what the engine already does. That can shift a drawn wedge by up to the one-degree repair sliver
clamp_gamma_pairapplies — correct, but visible if you compare a screenshot from before and after.The gap that let this survive was the test shape: the new sensor tests drive a gamma-only entry through the real
DiagnosticsBuilderinstead of hand-feeding theconfigurationdict. Issue #1292, which layers ablind_spot_slotsattribute on top ofblind_spot_ranges, depends on this fix but is not shipped here. -
The cloud-suppression summary states its trigger the right way round (#1301): The Configuration Summary rendered "skips sun tracking when weather in {sunny, partlycloudy, clear}".
ClimateProvidersetsis_sunnytoweather_state in weather_conditionand the priority-60 handler suppresses onnot r.is_sunny, so suppression fires when the live weather state is not in the configured set. The summary told users the exact opposite of what their configuration does, and matched the option's own help text only by accident.cloud.weather_innow reads "weather not in {…}". Fixing the operator rather than restructuring the shared "skips sun tracking when …" stem keeps the terse, copula-free register of the sibling fragments it sits beside in the joined condition list (lux < X lx,cloud > Y%); those three are already correct, and rephrasing only the weather clause positively would either break that sentence or drag them in with it. Since #906 made the DE and FR summary bundles live, German and French users saw the same inverted wording, so all three bundles land together. The existing test pinned the buggy string as correct, which is how this shipped in the first place; its assertion now expresses the real semantics. A related finding from the same audit — the summary presenting the weather-state check as an OR triple — is tracked in #1302 and is not fixed here.
Testing
12,565 tests passing.
Compatibility
Home Assistant 2026.3.0+ and Python 3.11+. No migration runs for this release, and no new or changed configuration options. The companion Lovelace card (jrhubott/adaptive-cover-pro-card) is a separate repo with its own release cycle and needs no update for this patch.
Adaptive Cover Pro ⛅ v2026.8.3-alpha.202608190431
🛠️ Develop build from
develop— unstable, for testing.
Auto-generated from the latest development code. Expect rough edges — not for production use.
Hit a problem? Open an issue and include this develop build version string.
What's Changed
- feat: show custom slot names in the config summary rules (#1190) by @jrhubott in #1193
- feat: serialize commands across covers via a named queue by @jrhubott in #1194
- fix: picker offers the current cover type; DE/FR label parity by @jrhubott in #1202
- fix: honour triage-exempt in release-issue-lifecycle (#1188) by @jrhubott in #1205
- fix: keep scripts/release log output out of the published release body (#1187) by @jrhubott in #1207
- fix: trust the strategy, not the thermometer, for climate labels (#1196) by @jrhubott in #1209
- fix: DE/FR cover-type wording slips (#1203) by @jrhubott in #1212
- fix: judge a coupled hold against its own position (#1179) by @jrhubott in #1213
- fix: keep tilt bounds on a tilt-only slot with no fixed tilt (#1215) by @jrhubott in #1217
- fix: give default-position handlers their own sunset tilt (#1214) by @jrhubott in #1218
- fix: Target Position follows the dispatched target when a bound clamps a hold (#1175) by @jrhubott in #1221
- fix: retire the sign-inverted vertical safety margin (#1173) by @jrhubott in #1224
- fix: give is_safety a defined lifetime across skips and resends (#1165) by @jrhubott in #1226
- feat: three-point tilt calibration for asymmetric Venetian slat travel (#1222) by @jrhubott in #1228
- fix: normalise inverse-tilt wire publish in venetian manual-override delta by @slangeder in #1227
- feat: sensor-gated constraints that act outside the time window (#943) by @jrhubott in #1229
- fix: stop an unset manual-override toggle wiping restored state (#1232) by @jrhubott in #1245
- fix: inherit drift-reset ineligibility on the tilt retry (#1234) by @jrhubott in #1246
- fix: expose sun-tracking min position in set_position_limits (#1242) by @jrhubott in #1252
- feat: guard the forward-merge and stale-checkout releases by @jrhubott in #1250
- docs: drop the HANDOFF read from live-diagnose startup by @jrhubott in #1255
- fix: refresh pipeline before the end-time override guard (#1241) by @jrhubott in #1257
- fix: anchor a blank start time to sunrise, not midnight (#1256) by @jrhubott in #1259
- fix: measure occupancy timeout expiry from timer start (#1266) by @jrhubott in #1268
- fix: gate climate low-light on the cloud-suppression hold (#1238) by @jrhubott in #1262
- feat: offer the companion card install in the options flow by @jrhubott in #1261
- fix: let cleared optional config fields round-trip (#1267) by @jrhubott in #1270
- fix: agree both manual-override axes on the threshold boundary (#1273) by @jrhubott in #1275
- fix: keep wait-for-target while a command is unreacted (#1139) by @jrhubott in #1276
- feat: add cover solar properties and an estimated solar gain sensor by @jrhubott in #1279
- fix: refuse to estimate solar gain from a non-W/m2 irradiance sensor by @jrhubott in #1281
- fix: clear the no-motion timer stamp when it expires (#1266) by @jrhubott in #1288
- fix: key the sunset edge on the configured boundary (#1287) by @jrhubott in #1289
- fix: make the vertical sill offset perpendicular (#1290) by @jrhubott in #1293
- fix: publish blind-spot gamma keys in diagnostics config by @jrhubott in #1295
- feat: publish per-slot blind-spot elevation gating (#1292) by @jrhubott in #1294
- fix: negate the cloud suppression weather condition (#1301) by @jrhubott in #1303
- feat: defer cloud suppression during the extreme-heat hold (#1272) by @jrhubott in #1305
- feat: scope the weather override to the time window (#1308) by @jrhubott in #1309
New Contributors
- @slangeder made their first contribution in #1227
Full Changelog: v2026.8.2...v2026.8.3-alpha.202608190431
Adaptive Cover Pro ⛅ v2026.8.3-alpha.202608181437
🛠️ Develop build from
develop— unstable, for testing.
Auto-generated from the latest development code. Expect rough edges — not for production use.
Hit a problem? Open an issue and include this develop build version string.
What's Changed
- feat: show custom slot names in the config summary rules (#1190) by @jrhubott in #1193
- feat: serialize commands across covers via a named queue by @jrhubott in #1194
- fix: picker offers the current cover type; DE/FR label parity by @jrhubott in #1202
- fix: honour triage-exempt in release-issue-lifecycle (#1188) by @jrhubott in #1205
- fix: keep scripts/release log output out of the published release body (#1187) by @jrhubott in #1207
- fix: trust the strategy, not the thermometer, for climate labels (#1196) by @jrhubott in #1209
- fix: DE/FR cover-type wording slips (#1203) by @jrhubott in #1212
- fix: judge a coupled hold against its own position (#1179) by @jrhubott in #1213
- fix: keep tilt bounds on a tilt-only slot with no fixed tilt (#1215) by @jrhubott in #1217
- fix: give default-position handlers their own sunset tilt (#1214) by @jrhubott in #1218
- fix: Target Position follows the dispatched target when a bound clamps a hold (#1175) by @jrhubott in #1221
- fix: retire the sign-inverted vertical safety margin (#1173) by @jrhubott in #1224
- fix: give is_safety a defined lifetime across skips and resends (#1165) by @jrhubott in #1226
- feat: three-point tilt calibration for asymmetric Venetian slat travel (#1222) by @jrhubott in #1228
- fix: normalise inverse-tilt wire publish in venetian manual-override delta by @slangeder in #1227
- feat: sensor-gated constraints that act outside the time window (#943) by @jrhubott in #1229
- fix: stop an unset manual-override toggle wiping restored state (#1232) by @jrhubott in #1245
- fix: inherit drift-reset ineligibility on the tilt retry (#1234) by @jrhubott in #1246
- fix: expose sun-tracking min position in set_position_limits (#1242) by @jrhubott in #1252
- feat: guard the forward-merge and stale-checkout releases by @jrhubott in #1250
- docs: drop the HANDOFF read from live-diagnose startup by @jrhubott in #1255
- fix: refresh pipeline before the end-time override guard (#1241) by @jrhubott in #1257
- fix: anchor a blank start time to sunrise, not midnight (#1256) by @jrhubott in #1259
- fix: measure occupancy timeout expiry from timer start (#1266) by @jrhubott in #1268
- fix: gate climate low-light on the cloud-suppression hold (#1238) by @jrhubott in #1262
- feat: offer the companion card install in the options flow by @jrhubott in #1261
- fix: let cleared optional config fields round-trip (#1267) by @jrhubott in #1270
- fix: agree both manual-override axes on the threshold boundary (#1273) by @jrhubott in #1275
- fix: keep wait-for-target while a command is unreacted (#1139) by @jrhubott in #1276
- feat: add cover solar properties and an estimated solar gain sensor by @jrhubott in #1279
- fix: refuse to estimate solar gain from a non-W/m2 irradiance sensor by @jrhubott in #1281
- fix: clear the no-motion timer stamp when it expires (#1266) by @jrhubott in #1288
- fix: key the sunset edge on the configured boundary (#1287) by @jrhubott in #1289
- fix: make the vertical sill offset perpendicular (#1290) by @jrhubott in #1293
- fix: publish blind-spot gamma keys in diagnostics config by @jrhubott in #1295
- feat: publish per-slot blind-spot elevation gating (#1292) by @jrhubott in #1294
- fix: negate the cloud suppression weather condition (#1301) by @jrhubott in #1303
- feat: defer cloud suppression during the extreme-heat hold (#1272) by @jrhubott in #1305
New Contributors
- @slangeder made their first contribution in #1227
Full Changelog: v2026.8.2...v2026.8.3-alpha.202608181437
Adaptive Cover Pro ⛅ v2026.8.3-alpha.202608180421
🛠️ Develop build from
develop— unstable, for testing.
Auto-generated from the latest development code. Expect rough edges — not for production use.
Hit a problem? Open an issue and include this develop build version string.
What's Changed
- feat: show custom slot names in the config summary rules (#1190) by @jrhubott in #1193
- feat: serialize commands across covers via a named queue by @jrhubott in #1194
- fix: picker offers the current cover type; DE/FR label parity by @jrhubott in #1202
- fix: honour triage-exempt in release-issue-lifecycle (#1188) by @jrhubott in #1205
- fix: keep scripts/release log output out of the published release body (#1187) by @jrhubott in #1207
- fix: trust the strategy, not the thermometer, for climate labels (#1196) by @jrhubott in #1209
- fix: DE/FR cover-type wording slips (#1203) by @jrhubott in #1212
- fix: judge a coupled hold against its own position (#1179) by @jrhubott in #1213
- fix: keep tilt bounds on a tilt-only slot with no fixed tilt (#1215) by @jrhubott in #1217
- fix: give default-position handlers their own sunset tilt (#1214) by @jrhubott in #1218
- fix: Target Position follows the dispatched target when a bound clamps a hold (#1175) by @jrhubott in #1221
- fix: retire the sign-inverted vertical safety margin (#1173) by @jrhubott in #1224
- fix: give is_safety a defined lifetime across skips and resends (#1165) by @jrhubott in #1226
- feat: three-point tilt calibration for asymmetric Venetian slat travel (#1222) by @jrhubott in #1228
- fix: normalise inverse-tilt wire publish in venetian manual-override delta by @slangeder in #1227
- feat: sensor-gated constraints that act outside the time window (#943) by @jrhubott in #1229
- fix: stop an unset manual-override toggle wiping restored state (#1232) by @jrhubott in #1245
- fix: inherit drift-reset ineligibility on the tilt retry (#1234) by @jrhubott in #1246
- fix: expose sun-tracking min position in set_position_limits (#1242) by @jrhubott in #1252
- feat: guard the forward-merge and stale-checkout releases by @jrhubott in #1250
- docs: drop the HANDOFF read from live-diagnose startup by @jrhubott in #1255
- fix: refresh pipeline before the end-time override guard (#1241) by @jrhubott in #1257
- fix: anchor a blank start time to sunrise, not midnight (#1256) by @jrhubott in #1259
- fix: measure occupancy timeout expiry from timer start (#1266) by @jrhubott in #1268
- fix: gate climate low-light on the cloud-suppression hold (#1238) by @jrhubott in #1262
- feat: offer the companion card install in the options flow by @jrhubott in #1261
- fix: let cleared optional config fields round-trip (#1267) by @jrhubott in #1270
- fix: agree both manual-override axes on the threshold boundary (#1273) by @jrhubott in #1275
- fix: keep wait-for-target while a command is unreacted (#1139) by @jrhubott in #1276
- feat: add cover solar properties and an estimated solar gain sensor by @jrhubott in #1279
- fix: refuse to estimate solar gain from a non-W/m2 irradiance sensor by @jrhubott in #1281
- fix: clear the no-motion timer stamp when it expires (#1266) by @jrhubott in #1288
- fix: key the sunset edge on the configured boundary (#1287) by @jrhubott in #1289
- fix: make the vertical sill offset perpendicular (#1290) by @jrhubott in #1293
- fix: publish blind-spot gamma keys in diagnostics config by @jrhubott in #1295
- feat: publish per-slot blind-spot elevation gating (#1292) by @jrhubott in #1294
- fix: negate the cloud suppression weather condition (#1301) by @jrhubott in #1303
New Contributors
- @slangeder made their first contribution in #1227
Full Changelog: v2026.8.2...v2026.8.3-alpha.202608180421
Adaptive Cover Pro ⛅ v2026.8.2
Highlights
2026.8.2 is an in-month patch: five bug fixes back-ported from develop, no new features, no configuration changes and nothing to migrate. Three of them cost users real cover movement. Manual overrides survive a Home Assistant restart again, after a regression that destroyed them on every reboot for every user (#1232). A blind with a blank start time and a configured end time no longer drives to its daytime default at local midnight (#1256). And the end-of-window reposition now actually fires instead of mistaking an ordinary in-window winner for an active override and skipping the move entirely (#1241). The remaining two fix a venetian drift-reset scope leak and a set_position_limits field that the Actions form never rendered.
Fixed
-
An unset manual-override toggle no longer wipes restored state (#1232):
_update_manager_and_coverstruthiness-testedmanual_toggle, which is a tri-statebool | None. That conflated theNonemeaning "no switch entity has restored yet" with theFalsemeaning "the user disabled manual-override detection". During platform setup theIntegration Enabledswitch fires a coordinator refresh three switch specs beforeManual Overriderestores the flag, so the reset loop ran while the toggle was stillNoneand destroyed every override the sensor had just rehydrated from the restore cache. Every user hit this on every reboot.Gating the reset on an explicit
is Falsefixes it. This is a follow-on to #1019 and PR #1021, whose fix (populatingmanager.coversearly) is correct and untouched. -
A blank start time anchors to sunrise, not midnight (#1256): With no start time configured and an end time set, the operational window re-opened at local midnight.
after_start_timemapped "no start configured" toTrue, putting the window's lower bound at midnight while_normalize_to_todaypinned the end onto the new date.is_activeflipped inactive to active at 00:00,check_transitionfiredon_window_open, and with every override handler declining in darkness the priority-0 default handler drove the cover to its daytime default.The night-hold branch added for #492 never reached these installs, because
compute_effective_defaultshort-circuits whensunset_pos is Noneand they had never configured a night position.TimeWindowManagernow takes an optionalsunrise_provider, and only the blank-start branch ofafter_start_timechanged: when an end bound is configured it consults sunrise and fails open toTruewhen none is available, so the window runs from sunrise to the configured end and never flips at midnight. The coordinator wires the provider as a closure over liveSunData, converting astral's UTC-aware sunrise to naive local. The config summary renders "from sunrise" for that shape, with DE and FR synced._resolve_start_datetime,_start_has_passed,window_explicitly_startedandcompute_effective_defaultare untouched. The mirror-image case, a start time set with the end left blank, is not fixed here; the shared_bound_is_configuredhelper prepares for it. -
The pipeline refreshes before the end-time override guard (#1241): The end-of-window reposition is a one-shot fired from the reconciliation tick, and its override guard read whatever
_pipeline_resultthe last coordinator cycle happened to write. This coordinator has no periodic update interval, so that result can predateend_timeby up to a full reconciliation interval, and any ordinary in-window winner such asSOLAR,CLOUDorGLARE_ZONEthen looked like an active override. The entire end-time move was skipped.managers/time_window.pylatches the close edge before invoking the callback, so nothing retried, and outside the clock window no other dispatch path will move the cover.I refresh the pipeline immediately before consulting the guard. Re-evaluating with the clock window already closed makes every window-gated handler decline, so the winner is
DEFAULTand the end-time position is sent. A genuinely activeCUSTOM_POSITION,MANUALorWEATHERslot still wins and is still deferred to, preserving the behaviour added in #895. -
Sun-tracking minimum position is visible in
set_position_limits(#1242):min_position_sun_trackingwas already wired intoFIELD_VALIDATORSand the_SECTION_POSITION_LIMITSfrozenset the service is registered with, and it carried translation entries in all three languages, butservices.yamlnever declared the field. Home Assistant builds the Actions form strictly fromservices.yaml, so the option was invisible in theset_position_limitsaction even though calling the service with it worked. It now has a field block with a slider selector matching the backend range (0-99, step 1, %).The same service had the mirror-image gap:
enable_position_matchingwas declared inservices.yamlbut had no translation entry in any language, so it rendered as raw English inside translated UIs. Both directions are now locked by a parity test modelled on theset_blind_spotguard from #247. The same class of drift in five other services is tracked separately in #1251 and is not fixed here. -
Drift-reset ineligibility is inherited on the tilt retry (#1234): The
sun_tracking_onlydrift-reset scope gate works correctly on the primary tilt send, but the #500 drift-retry re-send inside_verify_and_record_tiltcalled_send_tilt_commandwithout threadingdrift_reset_eligible. The flag fell back to itsTruedefault and re-armed drift accumulation on a send the scope had already ruled ineligible, so aDEFAULT-controlled venetian tilt ran a full reset cycle. The scope gate itself was never wrong: it readsControlMethodoffPositionContextrather than the command's trigger label, which is why the original diagnosis landed one frame short of the real seam._verify_and_record_tiltnow takesdrift_reset_eligiblekeyword-only and forwards it on the retry. Both verify call sites pass the raw parameter rather than the deriveddrift_reset_enabled, because the retry's own_send_tilt_commandre-derives the_reset_in_progressand threshold folds itself.apply_user_tiltleaked the same flag and now passes_drift_reset_eligible(None), so a card or service tilt is eligible only under theall_tilt_commandsscope. The retry still fires; only its accumulation is gated. This is a no-op under the defaultall_tilt_commandsscope and for every non-venetian cover type.
Testing
12,584 tests passing.
Compatibility
Home Assistant 2026.3.0+ and Python 3.11+. No migration runs for this release, and no new or changed configuration options. The companion Lovelace card (jrhubott/adaptive-cover-pro-card) is a separate repo with its own release cycle.
Adaptive Cover Pro ⛅ v2026.8.1
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
tiltfrom the pipeline registry's_MERGEABLEset so a losingDefaultHandlercould no longer leakdefault_tiltonto a winning handler. But three handlers answer withcompute_default_position()and label themselvesControlMethod.DEFAULTwithout ever supplying a tilt of their own, sosunset_tiltanddefault_tiltbecame unreachable whenever one of them won — venetian tilt-only covers held their last daytime slat angle all night.I extracted the resolution out of
DefaultHandlerintopipeline.helpers.compute_default_tilt(), preserving sunset precedence, thedefault_tiltfallback, the #503 clamp on the non-sunset branch and the #128 unclamped sunset carve-out.ClimateHandler(LOW_LIGHT / TRACKING_SEASON_GATE),CloudSuppressionHandler, andMotionTimeoutHandler's return-to-default branch now each state their own tilt.MotionTimeoutHandler's hold branch stays untilted — a hold must hold._MERGEABLEis 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()pickedcontrol_methodfrom theis_summer/is_wintertemperature predicates before consultingclimate_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_STRATEGIESfrozenset, 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_panelno longer deploys the heat blackout,day_night_shadeno 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/releaseno 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_infowrote to stdout, which put an "ℹ Using release notes from: …" line at the top of the published GitHub release body. I gavelog_info,log_success,log_warning,log_stepandlog_dry_runthe same>&2redirectlog_erroralready 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 themain "$@"entry point in aBASH_SOURCEguard 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-lifecyclehonourstriage-exempt(#1188, #1205): The release lifecycle workflow tagged every referenced open issuereleasedand 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 carriedreopenedbecause the beta.1 work didn't cover the whole request.I added a
triage-exemptguard to both mutation paths. IntagReferencedIssue()it goes first, before theawaiting-release/reopenedstripping, 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.