Skip to content

Releases: jasonjhofmann/aeolus

v0.7.2 — repo CI/workflow hardening + README fix (no code changes)

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 27 Aug 23:20
381a738

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)

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 25 Aug 01:30
791a29d

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

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 10 Aug 01:06
376a243

⚠️ 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_MILLIONUnitOfRatio.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)

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 10 Aug 00:53
b859a6e

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

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 19 Jun 01:54
b387305

Added

  • Action history now survives restarts. The recent_actions decision 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

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 19 Jun 00:37
6caedf8

Fixed

  • Attention status no longer flaps or contradicts its reason (FR-E6). A metric resting in its hysteresis band reported status: attention while reason said "OK — all metrics within range," and the per-space attention binary sensor toggled on slope noise (hundreds/day). attention is 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_action HA event (humanized in the Logbook) and is retained in a bounded recent_actions ring 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)

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 18 Jun 07:15
62bbf81

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

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 18 Jun 06:36
7453cb7

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.txt and documents the CI matrix; docs/SCAFFOLD.md tree 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)

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 18 Jun 06:23
33d28f7

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 —
    • lintruff 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%).
  • Validation (validate.yml): hassfest + HACS.
  • requirements_test.txt for local dev parity.

Fixed (surfaced by the new CI)

  • Removed the invalid homeassistant key from manifest.json (the HA floor lives in hacs.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)

Choose a tag to compare

@jasonjhofmann jasonjhofmann released this 18 Jun 05:44
e0c546a

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.json and the README already declared): requires-python>=3.13, ruff target-version=py313 pinned to the floor so the rewrite can never recur, and added the previously-missing homeassistant: "2025.4.0" key to manifest.json. All four version-floor sources now agree.

No functional/behavior change. ruff clean, mypy --strict clean, 105 tests pass.

🤖 Generated with Claude Code