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, andans_notification_rate_limited; automations can react in real time to the outcome of each individual channel delivery by @txxa in #47, #70 - Notification settled event —
ans_notification_settledfires once all fan-out tasks for a notification reach a terminal state, carrying per-recipient channel counts and arecipients_deliveredtotal so automations can detect total delivery failure by @txxa in #47 - Service response variable —
ans.send_notificationnow returns{"notification_id": "..."}usable viaresponse_variablein automations, enabling correlation with delivery outcome and acknowledgement events by @txxa in #47 - Stale channel Repairs issues — when a
notify.*service ormedia_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_failedevent witherror: "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 notifications —
ans.send_notificationnow accepts a top-levelactionsfield with up to 3 action button objects (actionidentifier,titlelabel, optionalurl); buttons are forwarded to the Mobile App and ignored by all other channels; button taps fire the standardmobile_app_notification_actionHA 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_acknowledgedHA bus event (carrying amethodfield and, for mobile events, adevice_namefield) and persists the record in a newans.acknowledgementsstorage 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
metadatafield is replaced by dedicated top-level fields inans.send_notification:context(key-value correlation data, internal-only),link(tap-action URL),image,video, andfile;channel_datais also exposed for adapter-specific overrides; onlyhttp/httpsURLs are accepted for URL fields; existing automations usingmetadatacontinue to work but will log a deprecation warning prompting migration to the new fields by @txxa in #53, #57 - Persistent notification rich content rendering —
image,video,file, andlinkfields are rendered as Markdown links and embeds directly in the HA sidebar notification; local image paths render as inline embeds;contextentries whose values match HA entity IDs are auto-linked to their history pages by @txxa in #53 - Signal Messenger rich content fields —
image,video, andfilefields are mapped automatically to Signal attachments or image URLs as appropriate, without requiringchannel_dataoverrides; a link set vialinkis 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/, orwww/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
offstate (e.g. Google Cast, Google Nest in standby) now receive directtts.speakdelivery 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), andretry_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— theiot_classis corrected fromlocal_pollingtolocal_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(viascripts/lint) instead of the outdatedblackmention, and documents how to run the test suite locally withrequirements-test.txtandscripts/testby @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,
actionsreference,data.tagand acknowledgement correlation,channel_dataoptions, and limitations - Signal Messenger — field handling,
channel_dataoptions, attachment path restriction, and limitations - TTS via Media Player — message format, volume management, Volume Restoration Registry, SSML mode, device state handling (
offvsunavailable), and limitations
- Persistent Notification — delivery behavior, Markdown field rendering (
- 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
metadatamigration 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_restorationentry, describing its fields and independent self-cleanup behavior - Delivery-events reference — added the previously undocumented
criticalityandmobile_tagpayload fields, and corrected theans_notification_settledTTL description to reflect its actual retry-scaled formula rather than a flat 1-hour value send_notificationservice description — corrected the claim that unrecognizedchannel_datakeys 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_notificationhas notargetparameter, since who is notified is decided entirely by recipient configuration
- Storage files reference — added the missing
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 newtest.ymlworkflow installsrequirements-test.txtand runspytestwith 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) undercustom_components/ans/brand/and removed theignore: "brands"override from the HACS validation workflow by @txxa in #68 - Delivery policy hardening —
RecipientNotificationPolicy.allowed_typesandDoNotDisturbConfig.allowed_criticalities/allowed_typesare converted fromlisttofrozenset, making the policy immutable end-to-end; removed the unusedmobile_device_idfield fromRecipientContactInfoand a dead, commented-outrequires_ha_uservalidation block from the delivery processor by @txxa in #68 - Fix manifest/version drift: removed the unused
VERSIONconstant fromconst.py(the manifest'sversionfield is now the single source of truth) and dropped the emptyhomekit,ssdp, andzeroconfkeys frommanifest.json, none of which apply to aservice-type integration by @txxa in #68 - Bump GitHub Actions workflow versions and the pinned
ruffversion inrequirements.txtby @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