Skip to content

v0.2.0

Latest

Choose a tag to compare

@txxa txxa released this 18 Jul 22:28

What's Changed

New Features

  • Delivery outcome events — four new HA bus events fire for every per-channel delivery result: ans_notification_delivered, ans_notification_filtered, ans_notification_failed, and ans_notification_rate_limited; automations can react in real time to the outcome of each individual channel delivery by @txxa in #47, #70
  • Notification settled eventans_notification_settled fires once all fan-out tasks for a notification reach a terminal state, carrying per-recipient channel counts and a recipients_delivered total so automations can detect total delivery failure by @txxa in #47
  • Service response variableans.send_notification now returns {"notification_id": "..."} usable via response_variable in automations, enabling correlation with delivery outcome and acknowledgement events by @txxa in #47
  • Stale channel Repairs issues — when a notify.* service or media_player.* entity disappears from HA, ANS automatically raises a Repairs issue in Settings → System → Repairs naming the missing channel and explaining how to resolve it; the issue is dismissed automatically once the channel is detected as active again; a cleanup sweep runs on every HA startup by @txxa in #48
  • Queue max depth — a new Queue max depth setting (default 500, range 10–5 000) bounds the delivery queue; excess tasks are dropped with a warning and an ans_notification_failed event with error: "queue_full" rather than causing unbounded memory growth; tasks in the persistent retry queue are deferred rather than discarded when the queue is full by @txxa in #49
  • Actionable mobile notificationsans.send_notification now accepts a top-level actions field with up to 3 action button objects (action identifier, title label, optional url); buttons are forwarded to the Mobile App and ignored by all other channels; button taps fire the standard mobile_app_notification_action HA bus event by @txxa in #51
  • Acknowledgement tracking — ANS tracks whether a delivered notification was acknowledged: tapping an action button or the notification body on a mobile push, or dismissing a persistent notification from the HA sidebar, fires an ans_notification_acknowledged HA bus event (carrying a method field and, for mobile events, a device_name field) and persists the record in a new ans.acknowledgements storage file that survives HA restarts, subject to the same configurable retention period as other audit data by @txxa in #52, #60

Enhancements

  • Structured notification payload fields — the metadata field is replaced by dedicated top-level fields in ans.send_notification: context (key-value correlation data, internal-only), link (tap-action URL), image, video, and file; channel_data is also exposed for adapter-specific overrides; only http/https URLs are accepted for URL fields; existing automations using metadata continue to work but will log a deprecation warning prompting migration to the new fields by @txxa in #53, #57
  • Persistent notification rich content renderingimage, video, file, and link fields are rendered as Markdown links and embeds directly in the HA sidebar notification; local image paths render as inline embeds; context entries whose values match HA entity IDs are auto-linked to their history pages by @txxa in #53
  • Signal Messenger rich content fieldsimage, video, and file fields are mapped automatically to Signal attachments or image URLs as appropriate, without requiring channel_data overrides; a link set via link is appended to the message body by @txxa in #53
  • Signal attachment path restriction — Signal Messenger attachments are validated before delivery and restricted to paths under the HA config, media/, or www/ directories; paths outside these directories — including ../ traversal sequences and symlinks that escape the allowed tree — are silently dropped with a warning log; the notification is still sent with any remaining valid attachments by @txxa in #50
  • TTS delivery to standby devices — media players in the off state (e.g. Google Cast, Google Nest in standby) now receive direct tts.speak delivery without being blocked; volume management is skipped because these platforms handle wakeup natively when a play command is received; errors from the attempt are treated as transient failures and retried with exponential backoff by @txxa in #54
  • Retry configuration bounds tightened — the allowed ranges for retry_base_delay (10–300 s), retry_backoff_factor (1.0–3.0), and retry_max_delay (60–3 600 s) are narrowed to safer defaults; existing configurations outside the new bounds are automatically clamped via a config entry migration (version 1 → 2) on upgrade by @txxa in #47
  • Integration class updated to local_push — the iot_class is corrected from local_polling to local_push, accurately reflecting the integration's event-driven architecture by @txxa in #57
  • Storage file names aligned to HA dot-separated convention — all five ANS storage files under <config>/.storage/ are renamed from the legacy underscore-and-extension format (ans_notifications.json, ans_delivery_attempts.json, ans_retry_queue.json, ans_acknowledgements.json, ans_volume_restoration) to the HA dot-separated convention (ans.notifications, ans.delivery_attempts, ans.retry_queue, ans.acknowledgements, ans.volume_restoration); a backward-compatible migration routine runs automatically during config-entry upgrade to rename any pre-existing files, resolving name conflicts by keeping the newer file by @txxa in #62

Bug Fixes

  • Fix config flow validation errors: field validation errors in the recipient and system settings wizard now correctly display localized HA error messages instead of raw internal strings; the error text for the Rate Limit and Retry Attempts fields was corrected to read "non-negative integer" rather than showing unresolved {min} / {max} placeholder text by @txxa in #38
  • Fix Do Not Disturb settings dropped on recovered retries: a notification's retry task recovered after an HA restart lost the recipient's Do Not Disturb configuration, causing the retry to bypass DND schedules and bypass rules it should have respected by @txxa in #70

Documentation

  • AI coding agent guidance (AGENTS.md) — new guide for AI coding agents covering project intent, always/never rules, architecture, build/lint/test commands, observability conventions, and git/PR conventions; a new CLAUDE.md points Claude Code to it and documents working-style rules; the README now notes that development of the integration was assisted by AI tools by @txxa in #68
  • Contributing guide refreshed — CONTRIBUTING.md now references ruff (via scripts/lint) instead of the outdated black mention, and documents how to run the test suite locally with requirements-test.txt and scripts/test by @txxa in #68
  • New Channel Reference (channels.md) — comprehensive per-channel reference relocated from Advanced Topics into a dedicated document by @txxa in #56:
    • Persistent Notification — delivery behavior, Markdown field rendering (image, video, file, link, context), acknowledgement via sidebar dismissal, and limitations
    • Mobile App — field handling, actions reference, data.tag and acknowledgement correlation, channel_data options, and limitations
    • Signal Messenger — field handling, channel_data options, attachment path restriction, and limitations
    • TTS via Media Player — message format, volume management, Volume Restoration Registry, SSML mode, device state handling (off vs unavailable), and limitations
  • Existing docs updated across How It Works, Getting Started, Overview, Advanced Topics, Troubleshooting, and Usage Examples to document all new features, including delivery outcome events, notification settled, queue depth, stale channel Repairs, actionable notifications, acknowledgement tracking, structured payload fields, standby TTS delivery, the deprecated metadata migration guide, acknowledgement persistence, and updated storage file name references to the new dot-separated convention by @txxa in #47, #48, #49, #50, #51, #52, #53, #54, #57, #60, #62
  • Documentation audit fixes — corrected several inaccuracies found across the docs by @txxa in #70:
    • Storage files reference — added the missing ans.volume_restoration entry, describing its fields and independent self-cleanup behavior
    • Delivery-events reference — added the previously undocumented criticality and mobile_tag payload fields, and corrected the ans_notification_settled TTL description to reflect its actual retry-scaled formula rather than a flat 1-hour value
    • send_notification service description — corrected the claim that unrecognized channel_data keys are silently ignored by every adapter; the Mobile App channel forwards any key as-is
    • README and Overview — refreshed the feature list and added a clarification that ans.send_notification has no target parameter, since who is notified is decided entirely by recipient configuration

Other Changes

  • Increase test coverage for all new features and refactor async notification handling by @txxa in #47, #48, #49, #50, #51, #52, #53, #54, #55, #60, #62, #70
  • Bump GitHub Actions workflow dependencies by @txxa in #57
  • CI quality gates added — a new CodeQL SAST workflow analyzes the Python codebase on every push, on pull requests to main, and via manual dispatch; a new test.yml workflow installs requirements-test.txt and runs pytest with coverage reporting, uploading the coverage report as a build artifact by @txxa in #68
  • Full HACS brand validation enabled — added the required icon/logo assets (icon.png, icon@2x.png, logo.png, logo@2x.png, dark_logo.png, dark_logo@2x.png) under custom_components/ans/brand/ and removed the ignore: "brands" override from the HACS validation workflow by @txxa in #68
  • Delivery policy hardeningRecipientNotificationPolicy.allowed_types and DoNotDisturbConfig.allowed_criticalities/allowed_types are converted from list to frozenset, making the policy immutable end-to-end; removed the unused mobile_device_id field from RecipientContactInfo and a dead, commented-out requires_ha_user validation block from the delivery processor by @txxa in #68
  • Fix manifest/version drift: removed the unused VERSION constant from const.py (the manifest's version field is now the single source of truth) and dropped the empty homekit, ssdp, and zeroconf keys from manifest.json, none of which apply to a service-type integration by @txxa in #68
  • Bump GitHub Actions workflow versions and the pinned ruff version in requirements.txt by @txxa in #68
  • Consolidated internal maintainer tooling (prompt templates, release-note drafts, feature specs) under a single gitignored .internal/ directory and documented the process for keeping .internal/features/ in sync with code changes in AGENTS.md by @txxa in #70

Full Changelog: v0.1.1...v0.2.0