Skip to content

evolutions - #4

Closed
slemeur91 wants to merge 1 commit into
crandler:mainfrom
slemeur91:evolutions
Closed

slemeur91 wants to merge 1 commit into
crandler:mainfrom
slemeur91:evolutions

Conversation

@slemeur91

Copy link
Copy Markdown

CoverAutomatic 2.0.0 - Major release consolidating all changes since 1.61.1

New features

  • French language added alongside English and German (panel, card, services, logs, entities, built-in scenarios).
  • Rules: Home Assistant conditions (form or YAML), condition groups with NOT, scenarios per rule, dawn/dusk conditions, outdoor vs room temperature, room occupancy, safety rule, rule duplication.
  • Covers: keep position when the window opens, learned travel time, automatic resume when the position matches the rule, resend of lost commands.
  • Settings: wind protection position, thresholds driven by entities, configurable sun-on-facade behaviour, temperature colour choice.
  • Dashboard card, per-cover sensors and global entities (wind protection, paused/manual/locked counters).
  • Log filter per cover.

Improvements

  • Reorganised cover sheet and settings, clearer rule editor, safety badge in scenarios, better mobile layout, lighter live updates.

Fixes

  • Window lock keeps priority over wind and survives restarts; unknown window sensors never lower a cover.
  • False manual pauses removed.
  • Complete export and validated import of backups.
  • Many stability fixes after three full code audits; 1325 automated tests.

CoverAutomatic 2.0.0 - Major release consolidating all changes since 1.61.1

New features
- French language added alongside English and German (panel, card, services, logs, entities, built-in scenarios).
- Rules: Home Assistant conditions (form or YAML), condition groups with NOT, scenarios per rule, dawn/dusk conditions, outdoor vs room temperature, room occupancy, safety rule, rule duplication.
- Covers: keep position when the window opens, learned travel time, automatic resume when the position matches the rule, resend of lost commands.
- Settings: wind protection position, thresholds driven by entities, configurable sun-on-facade behaviour, temperature colour choice.
- Dashboard card, per-cover sensors and global entities (wind protection, paused/manual/locked counters).
- Log filter per cover.

Improvements
- Reorganised cover sheet and settings, clearer rule editor, safety badge in scenarios, better mobile layout, lighter live updates.

Fixes
- Window lock keeps priority over wind and survives restarts; unknown window sensors never lower a cover.
- False manual pauses removed.
- Complete export and validated import of backups.
- Many stability fixes after three full code audits; 1325 automated tests.
@mycanaletto

Copy link
Copy Markdown

Great job, and thanks for all these improvements—I'll give it a try soon.

I've noticed that when you delete a panel, the device and entities aren't deleted.
image

@crandler

crandler commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Hi @slemeur91, thanks a lot for this. There's clearly a lot of work in it.

I have to be upfront though: I won't merge a change of this size. It's a single 14.5k-line commit with about 15 features, a new major version and changes to how the integration hooks into the user's setup (e.g. auto-registering a Lovelace resource). I can't review that properly, and I'd have to maintain all of it long-term. So I'm closing this PR.

If you want to keep developing in this direction, please do it as your own fork. The MIT license fully allows that. If you publish it, e.g. via HACS, please:

  • change codeowners, documentation and issue_tracker in manifest.json so bug reports for your version reach you
  • ideally use a different name and domain, so users can tell the two apart and both can be installed side by side

Single features are welcome here. Please open an issue first that describes the use case, so we can agree on it before any code is written. After that, a small, focused PR against current main works best. I'd be happy to take the French translation as a first one.

One heads-up for your fork: the branch currently contains unresolved git stash pop conflict markers in 9 files, including manifest.json, __init__.py, api.py, sun.py and the panel JS, so it won't load as is.

Thanks again for the effort. I'm looking forward to the French translation PR, and feel free to reach out if anything in the codebase is unclear.

@crandler crandler closed this Oct 1, 2026
crandler added a commit that referenced this pull request Oct 1, 2026
…(v1.62.2)

Both delete handlers only removed the entry from storage. The device and its entities stayed in the device and entity registries, so Home Assistant kept showing them (reported on PR #4). The handlers now remove the device; the entity registry drops its entities and states with it.

async_remove_config_entry_device lets users delete devices left behind by earlier versions on their device page. Devices of configured covers, facades and the integration itself stay protected.

The regression tests run on a real Home Assistant instance with real registries, adding the entities through the integration's own platform setup.
@crandler

crandler commented Oct 1, 2026

Copy link
Copy Markdown
Owner

Thanks for spotting this, @mycanaletto. It affected the released version too: deleting a cover or facade in the panel only removed it from CoverAutomatic's own config, while the device and its entities stayed in Home Assistant.

Fixed in v1.62.2. Deleting now removes the device and its entities as well, and devices left behind by earlier deletes can be deleted on their device page.

crandler added a commit that referenced this pull request Oct 2, 2026
Adds translations/fr.json for the config flow, options flow and entity names, states and status attributes, plus an fr block in the panel's I18N object with all 277 keys of the English block. The panel picks it from hass.language like the other languages. Strings from the French translation in PR #4 were reused where the English source is unchanged; the rest is translated from the current English text. Requested in GitHub issue #5.

New test_translations.py checks that every translations/*.json and every panel language block has exactly the English keys and the same {placeholders}, and that strings.json matches en.json. The panel object literal is parsed without a JS runtime, so a new key missing in one language now fails CI.
crandler added a commit that referenced this pull request Oct 2, 2026
… (v1.63.1)

The status sync read an unavailable, unknown or missing lock sensor as a closed window. A LOCKED cover was unlocked on the next cycle, and the matching rule could then lower it at a window that was still open, e.g. during a Zigbee bridge outage or with an empty sensor battery. The contact sensor event handler already ignored unreadable states; the sync did not.

The sync now keeps an existing lock while the lock sensor has no readable state and never moves the cover for it. A readable sensor state or a resume ends the lock as before. Covers that were LOCKED at shutdown keep their lock after a restart if their sensor is still unreadable at the first sync; a readable state at that point re-derives the status as before. A cover that is not locked is unaffected by an unreadable sensor.

Found while reviewing PR #4. The regression tests run on a real Home Assistant instance.
crandler added a commit that referenced this pull request Oct 2, 2026
… (v1.63.1)

Deleting a cover or facade only removed it from the rules that referenced it. A rule left without any cover or facade counts as global and applies to every cover, so a rule meant for one room started moving all covers, e.g. after replacing an actuator and deleting the old cover.

Such a rule is now disabled and a warning is logged. Rules that keep another cover or facade stay enabled, and rules that were global on purpose are not touched.

Found while reviewing PR #4.
crandler added a commit that referenced this pull request Oct 2, 2026
….63.1)

The panel saves settings per section, so many settings have no stored value until their section is saved once. For every setting missing in the import file, the import copied the current stored value and wrote None where there was none. A backup of a partly configured instance, imported again, left enabled = None and min_position_change = None. The backend read enabled = None as off (no rule evaluation) while the panel still showed it as on, and min_position_change = None raised a TypeError on the next move, stopping all covers.

The import now copies only settings that are actually stored, so unsaved ones keep their defaults. update_check_enabled joins the preserved settings; it was missing from the list, so an import dropped the opt-out. None in a setting that needs a value is repaired on import and on load: switches become False, matching what the backend did with None, so an automation that the old import switched off stays off instead of starting to move covers right after the update (the panel now shows it as off). Numbers fall back to their defaults.

Found while reviewing PR #4. The regression tests export and import through the panel's WebSocket commands on a real Home Assistant instance.
crandler added a commit that referenced this pull request Oct 2, 2026
…63.1)

The import replaced each cover's status, pause_until and last_position_change with the values stored in the file. These are runtime state, not configuration:

- A cover paused while importing got pause_until from the file, usually None. The coordinator kept it PAUSED, and the expiry check needs a pause_until, so the pause never ended until a resume or restart. The panel showed the file's status meanwhile.
- A file status "locked" counted as locked at shutdown on the next restart, so with the lock sensor not loaded yet the cover started out locked.

Existing covers now keep their live values, new covers start in AUTO without pause or last change.

Found while reviewing PR #4.
crandler added a commit that referenced this pull request Oct 2, 2026
…dow closes (v1.63.2)

Ending wind protection with a window still open re-locked the cover. When the cover already stood at the lock position, which is the usual case because wind protection opens it fully and the default lock position is 100, the lock was set without a pre-lock entry. _unlock_cover returns early without one, so neither the window-close event nor the status sync released the cover. It stayed LOCKED until a resume, the automation switch or a restart.

The branch now records AUTO as the pre-lock state, the status the deactivation assigns to a cover without open sensors. A cover with automation disabled still ends in MANUAL through the sync and does not move.

Found while reviewing PR #4. The regression tests run on a real Home Assistant instance and cover both lock branches of the deactivation.
crandler added a commit that referenced this pull request Oct 2, 2026
The contact sensor handler set LOCKED or VENTING over WIND_PROTECTED. A tilted window sent the vent position to a cover that was still opening for the storm and stopped it partway until the next sync, up to 60 s later; an open window re-sent the lock position. That sync then re-activated wind protection and sent every cover a new open command.

The handler now returns early while wind protection is active, like the cover state handler. Ending wind protection already re-derives lock and vent from the sensor states, so a window opened during the storm is picked up then.

Found while reviewing PR #4. The regression test runs on a real Home Assistant instance.
crandler added a commit that referenced this pull request Oct 2, 2026
…s running (v1.63.3)

Closing a window while its cover was still opening for it took the intermediate or stale position as the expected one. The arrival at the lock position fell into the settle time and was ignored, so the next apply cycle read it as a manual override and paused the cover, which then stayed open for the pause duration, e.g. after a door was opened only briefly. The same happened when the window went from open to tilted during the move.

The unlock now keeps the lock target as expected position and marks the cover as settling while the lock move is in flight: within the settle time of the command or while the cover reports opening/closing, unless it already reached the target. The existing settle check reconciles the arrival, then the rule target applies. A cover at rest is synced from its state as before, so a cover moved by hand during a long lock is still handed back to the rules.

Two existing tests assumed an instant unlock: one patched the clock without a value, the other closed the window in the same instant as the lock command without the cover ever arriving. Both now model a cover at rest. Found while reviewing PR #4. The regression tests run on a real Home Assistant instance with a controlled clock.
crandler added a commit that referenced this pull request Oct 2, 2026
…1.63.4)

With a command stagger above 0 the apply cycle sleeps between two cover commands. It read the cover status before the pause and sent the rule target computed for it afterwards. A window opened during the pause locked the cover, yet the stale target still closed it; a tilted window let it go below the vent minimum.

After the pause the cycle now re-reads the status and skips the cover when it changed (window opened, tilted, manual override). The next cycle evaluates it with the new status, a tilted window still gets the vent minimum.

Found while reviewing PR #4. The regression tests run on a real Home Assistant instance with a real stagger pause, plus a guard that an unchanged cover still moves after the pause.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants