Releases: jasonjhofmann/aeolus
Release list
v0.7.2 — repo CI/workflow hardening + README fix (no code changes)
Changed
- Repository CI/workflow hardening only — no integration code changes.
Gate the @claude workflows on the triggering actor having write access,
cite the entrypoint the pinned action actually runs (run.ts), and stop
running the automated review on Dependabot PRs. - README: named the HACS badge and repeated the add-integration menu path in
the manual-install section, replacing directional "above" references
(docs-only, per the Google style guide's ban on directional cross-references).
v0.7.1 - README rewrite + screenshots for the HACS submission (docs only)
Documentation-only release. No code change.
- README rewritten for the HACS default-store submission: feature-forward introduction, badges, one-click My Home Assistant install links, and seven live screenshots (managed CO2 falling to target with slope/ACH/control-ladder cards, the config-flow dialogs, a Space device page with the decision Activity log, and the attributes pane).
- Every claim re-verified against the code; quality-scale docs sections retained.
- Prose follows the Google developer documentation style guide.
CI on this commit: ruff, mypy --strict, the full test suite, hassfest, and HACS validation all green.
Full changelog: https://github.com/jasonjhofmann/aeolus/blob/main/CHANGELOG.md
v0.7.0 — UnitOfDensity/UnitOfRatio; requires HA 2026.7.0
⚠️ Breaking: minimum Home Assistant is now 2026.7.0 (Python 3.14)
Home Assistant deprecated the CONCENTRATION_* unit constants in core#175189 (shipped in 2026.8); they are removed in HA Core 2027.8. This release migrates to the UnitOfDensity / UnitOfRatio StrEnums ahead of that removal.
CONCENTRATION_PARTS_PER_MILLION → UnitOfRatio.PARTS_PER_MILLION (the unit on the CO₂ Target number). 116 tests pass; ruff/mypy(strict)/syntax-floor/hassfest/HACS green.
UnitOfDensity/UnitOfRatio first ship at 2026.7.0 (verified absent at the 2026.6.0 tag), and HA 2026.7.0 declares requires-python = ">=3.14.2" — so the Python floor moves to 3.14 with it. On Home Assistant older than 2026.7.0 this version will not load; stay on v0.6.2.
No unit string, entity state, or recorded statistic changes. The deprecated names already resolved to these exact enum members with byte-identical values, so states, unit_of_measurement attributes, history and long-term statistics are untouched. The change removes a startup deprecation warning and pre-empts the 2027.8 removal.
Full changelog: https://github.com/jasonjhofmann/aeolus/blob/main/CHANGELOG.md
v0.6.2 — canonical micro sign (U+03BC)
Home Assistant's canonical microgram unit is U+03BC GREEK SMALL LETTER MU, not U+00B5 MICRO SIGN (verified byte-level in homeassistant/const.py back to the 2025.12 tag). This release corrects that.
METRIC_UNIT in const.py fed the PM sensors' native_unit_of_measurement, so this was the one functional instance across the fleet. Config-flow labels in strings.json/translations/en.json corrected to match, so the UI no longer renders two different mu glyphs. 116 tests pass; ruff/mypy/hassfest/HACS green.
No user-visible symptom: HA resolves the displayed unit through the concentration converter, so live entities already reported U+03BC. µm (micrometres) is deliberately left on U+00B5 — that is the correct character and has no HA constant to match.
Full changelog: https://github.com/jasonjhofmann/aeolus/blob/main/CHANGELOG.md
v0.6.1 — persistent action history
Added
- Action history now survives restarts. The
recent_actionsdecision ring (FR-U2) is persisted to.storage— debounced saves on each action, flushed on unload, restored on setup — so the log is no longer lost on every Home Assistant restart (the ring is in-memory). The viewer's Activity tab now keeps real depth across restarts instead of relying on HA-history backfill.
116 tests pass; ruff/mypy(strict)/py3.13-compile/hassfest/HACS green.
Full changelog: https://github.com/jasonjhofmann/aeolus/blob/main/CHANGELOG.md
v0.6.0 — attention fix + action history
Fixed
- Attention status no longer flaps or contradicts its reason (FR-E6). A metric resting in its hysteresis band reported
status: attentionwhilereasonsaid "OK — all metrics within range," and the per-spaceattentionbinary sensor toggled on slope noise (hundreds/day).attentionis now keyed on the metric's engaged tier (engage/release hysteresis) with the engine's convergence deadband; a partially-stale space surfaces the stale sensor in its reason. Status and reason are consistent by construction.
Added
- Durable action history (FR-U2). Each operator-relevant decision (actuator on/off with driving space + metric/tier, manual-override yield, outdoor-AQ veto, runtime cap) now fires an
aeolus_actionHA event (humanized in the Logbook) and is retained in a boundedrecent_actionsring in diagnostics.
115 tests pass; ruff/mypy(strict)/py3.13-compile clean. Not yet deployed to live HA.
Full changelog: https://github.com/jasonjhofmann/aeolus/blob/main/CHANGELOG.md
v0.5.5 — internal refactor (no behavior change)
Internal refactor only — no behavior or public-API change for users. (Audit P3, M3-1.)
Extracted the runtime-state dataclasses (MetricRuntime, SpaceRuntime, ActuatorRuntime) into a new leaf module runtime.py, fixing an inverted dependency: safety.py previously imported these from engine.py, which forced engine.py to lazy-import safety/controller inside methods to dodge a circular import. Those imports are now top-level, and safety/controller no longer depend on engine at runtime. The types are still re-exported from engine for backward compatibility.
All six CI jobs green; 107 tests pass.
🤖 Generated with Claude Code
v0.5.4 — config-time validation
Enforces at config time what the documentation already promised (audit P2).
Added
- Space: the High threshold must be above the Target — an invalid combination is now rejected in the config flow (add and reconfigure) with a clear error, instead of silently producing a degenerate CO₂ tier with no deadband.
- Actuator (FR-C8): a recirculating air purifier (the Filter mechanism) can no longer be assigned to a Space's CO₂ ventilation (Spaces it ventilates) — the flow rejects it, since a filter removes particulates, not CO₂. (The controller already prevented this at runtime; now it's caught up front, as the docs state.)
Changed
- README "Testing" now uses
requirements_test.txtand documents the CI matrix;docs/SCAFFOLD.mdtree updated for the CI workflows.
All six CI jobs green (lint, syntax-floor 3.13, pytest 3.13/3.14, hassfest, HACS). 107 tests.
🤖 Generated with Claude Code
v0.5.3 — CI + validation (release safety net)
Adds the Continuous Integration that was missing when v0.5.1 shipped an import break — and, on its very first run, caught and fixed pre-existing validation issues.
Added
- CI (
.github/workflows/ci.yml): on every push/PR —- lint —
ruff check+ruff format --check+mypy --strict; - syntax-floor — compiles on Python 3.13 (the support floor), so a 3.14-only construct (the v0.5.1
except A, B:regression) fails in CI instead of on a user's HA 2025.4 install; - test — full suite on a Python 3.13 + 3.14 matrix, 90% coverage gate (currently 96%).
- lint —
- Validation (
validate.yml): hassfest + HACS. requirements_test.txtfor local dev parity.
Fixed (surfaced by the new CI)
- Removed the invalid
homeassistantkey frommanifest.json(the HA floor lives inhacs.json; hassfest rejects it on the manifest — corrects v0.5.2). - Replaced the HTML-like
<pollutant>placeholder with[pollutant]in flow descriptions (hassfest forbids HTML in translations). - Added
CONFIG_SCHEMA = cv.config_entry_only_config_schema(DOMAIN). - Set GitHub repository topics (required by HACS).
All six CI jobs green (lint, syntax-floor, pytest 3.13, pytest 3.14, hassfest, HACS). No change to control behavior.
🤖 Generated with Claude Code
v0.5.2 — fix import break on HA 2025.4+ (Python 3.13)
Critical fix — please update from v0.5.1
v0.5.1 failed to import on Home Assistant 2025.4–2025.12 (Python 3.13). A ruff target-version=py314 setting rewrote except (TypeError, ValueError): into the bare Python-3.14-only form except TypeError, ValueError: (PEP 758) in engine.py and safety.py — a hard SyntaxError on Python 3.13, so the integration would not load at all on those HA versions. (v0.5.0 and earlier were unaffected.)
Fixed
- Restored the parenthesized
except (TypeError, ValueError):; verified all source parses under Python 3.13.
Changed
- Corrected the supported floor to Home Assistant 2025.4 / Python 3.13 (what
hacs.jsonand the README already declared):requires-python>=3.13, rufftarget-version=py313pinned to the floor so the rewrite can never recur, and added the previously-missinghomeassistant: "2025.4.0"key tomanifest.json. All four version-floor sources now agree.
No functional/behavior change. ruff clean, mypy --strict clean, 105 tests pass.
🤖 Generated with Claude Code