-
-
Notifications
You must be signed in to change notification settings - Fork 19
Technical: Notifications
This document provides technical details about the ChoreOps notification system architecture for developers and advanced users.
Terminology: This document uses terms like "chore ID", "assignee ID", and "entity ID". For precise definitions of Item vs Entity, Internal ID, and Domain Item terminology, see ARCHITECTURE.md - Lexicon Standards.
Notifications use a smart tagging system to prevent notification spam. When a new notification is sent with the same tag, it replaces the previous notification instead of stacking.
Each notification is tagged with a unique identifier combining the config entry ID, entity type, entity ID, and assignee ID:
Multi-Instance Support: The config entry ID is included as the first identifier to ensure notifications from different ChoreOps integrations don't interfere with each other. Each identifier is truncated to 8 characters to stay within mobile notification tag limits.
| Notification Type | Tag Pattern | Example |
|---|---|---|
| Chore Approval | choreops-status-{entry_id}-{chore_id}-{assignee_id} |
choreops-status-abc12345-def67890-ghi01234 |
| Reward Approval | choreops-rewards-{entry_id}-{reward_id}-{assignee_id} |
choreops-rewards-abc12345-xyz78901-ghi01234 |
| Overdue Chores | choreops-overdue-{entry_id}-{chore_id}-{assignee_id} |
choreops-overdue-abc12345-def67890-ghi01234 |
| Due Soon Chores | choreops-due_window-{entry_id}-{chore_id}-{assignee_id} |
choreops-due_window-abc12345-def67890-ghi01234 |
| System Alerts | choreops-system-{entry_id}-{assignee_id} |
choreops-system-abc12345-ghi01234 |
When Zoë claims multiple chores, each notification remains independent:
- Zoë claims "Make Bed" (chore1) → Tag:
choreops-status-entry123-chore1ab-zoe12345 - Zoë claims "Feed Dog" (chore2) → Tag:
choreops-status-entry123-chore2cd-zoe12345
Result: Approvers see both notifications because each chore has a unique tag.
When approvers press "Remind in 30 min":
- A new notification is scheduled with the same tag as the original chore
- After 30 minutes, the reminder replaces only that specific chore's notification
- Other chore notifications remain untouched
The integration automatically clears certain notifications from mobile devices to prevent stale action buttons and notification spam.
Approval/Disapproval Clearing (Multi-Approver Support):
- When any approver approves or disapproves a chore/reward (via notification button OR dashboard), the integration sends a
clear_notificationmessage to all approver devices - This removes the original "Chore/Reward Claimed" notification with action buttons from all approvers
- Example: Assignee claims chore → Both approvers notified → Approver 1 approves via notification button → Notification cleared from both approver devices
- Why: Prevents other approvers from seeing stale action buttons for already-processed claims
Claim/Approval Path (Due Soon notifications):
- When an assignee claims a "Chore Due Soon" notification, it's automatically replaced by "Chore Claimed" sent to approvers
- When a chore is approved, the "Chore Claimed" notification is cleared from all approver devices
Which Notifications Are Auto-Cleared:
- ✅ Chore Claimed - Cleared when any approver approves/disapproves (any path)
- ✅ Reward Claimed - Cleared when any approver approves/disapproves (any path)
- ✅ Chore Overdue (Assignee) - Cleared when assignee claims chore OR approver approves
- ✅ Chore Due Soon (Assignee) - Cleared when assignee claims chore OR approver approves
- ✅ Chore/Reward Reminder (30 min) - Cleared when any approver approves/disapproves
- ✅ Chore Disapproved - Auto-clears original approver claim notifications
- ❌ All other notifications - Remain until dismissed by user
The notification system now provides comprehensive auto-clearing for assignee notifications:
Chore State Transitions:
- When an assignee claims an overdue chore → Overdue notification is cleared from their device
- When an assignee claims a due-soon chore → Due-soon notification is cleared from their device
- When an approver approves any chore → Both overdue AND due-soon notifications cleared from the assignee's device
- When an approver disapproves a chore → Assignee receives disapproval notification, approver claim notifications are cleared
Why This Matters: Assignees no longer see stale "Chore Overdue" or "Claim Now" notifications after they've taken action. This prevents confusion and duplicate claims.
When an assignee has multiple pending chores waiting for approval, the integration uses smart aggregation to reduce notification clutter for approvers:
How It Works:
- Assignee claims multiple chores → Each claim generates individual notifications to approvers
- Approver approves one chore → Old notification is cleared and replaced with an updated aggregated notification:
- Shows: "[Assignee] has N pending chores. Latest: [Chore Name] (X points)"
- Includes: Action buttons for the most recent pending chore
- Approver continues approving → Notification updates with new count and latest chore details
- Last chore approved → No replacement notification sent (all approvals complete)
Rewards: Do not use aggregation. Each reward approval sends independent notifications and clears the original claim notification.
Why This Matters: Approvers with multiple assignees/chores see consolidated status updates instead of a growing list of individual notifications.
Overdue notification routing is payload-driven to keep manager boundaries clean and avoid duplicate attempts.
Emit contract (ChoreManager):
- Emits one overdue event per assignee target
- Includes
user_idas the single notification target - Includes
overdue_message_typewith values:defaultsteal_available
Consume contract (NotificationManager):
- Sends overdue notifications only to payload
user_id(no rotation fan-out) - Selects assignee overdue message key strictly from
overdue_message_type - Falls back to the default overdue assignee message when the field is missing or unknown
- Keeps approver overdue message/action behavior unchanged
Mode behavior:
- Rotation + allow-steal may emit
steal_availablefor non-turn assignees - Independent / Shared (All) / Shared (First) continue using
default
Notifications are translated per-user using the integration's custom translation architecture:
- 14 languages supported via Crowdin (English, Spanish, Dutch, French, German, Italian, and more)
- Per-user preferences - Users can use different languages
- Automatic fallback to English for missing translations
-
Translation files:
translations_custom/{lang}_notifications.json -
Translation key pattern:
{notification_type}_{audience}(e.g.,chore_approved_kid,badge_earned_parent)- These key suffixes are legacy translation identifiers and remain unchanged.
- Integration determines recipient's language preference
- Loads appropriate translation file (
en_notifications.json,es_notifications.json, etc.) - Formats notification with dynamic placeholders (
{kid_name},{chore_name},{points}, etc.) - Sends translated notification to user's mobile device
Key Features:
- Titles, messages, and action button labels all translated
- Emojis preserved across all languages
- Placeholder replacement happens after translation
For complete translation architecture details (sensor entities, translation constants, Crowdin workflow), see ARCHITECTURE.md - Translation Architecture.
-
Notification Manager:
managers/notification_manager.py- Core notification logic, smart tagging, auto-clearing, aggregation -
Action Handler:
notification_action_handler.py- Processes action button presses from mobile notifications -
Translation Files:
translations_custom/{lang}_notifications.json- Notification text for 14 languages
All notification constants follow the TRANS_KEY_NOTIF_* pattern in const.py:
-
TRANS_KEY_NOTIF_TITLE_*- Translation keys for notification titles -
TRANS_KEY_NOTIF_MESSAGE_*- Translation keys for notification messages -
TRANS_KEY_NOTIF_ACTION_*- Translation keys for action button labels
Example Pattern:
TRANS_KEY_NOTIF_TITLE_CHORE_APPROVED_KID = "chore_approved_kid"
TRANS_KEY_NOTIF_MESSAGE_CHORE_APPROVED_KID = "chore_approved_kid"For complete constant naming conventions and patterns, see DEVELOPMENT_STANDARDS.md - Constant Naming Standards.
Architecture & Design:
-
ARCHITECTURE.md - Complete integration architecture
- Lexicon Standards - Item vs Entity terminology
- Translation Architecture - Translation system design
- Layered Architecture - Manager/Helper/Engine/Util separation
Development Standards:
-
DEVELOPMENT_STANDARDS.md - Coding guidelines and patterns
- Constant Naming Standards - All constant prefix patterns
- Localization Standards - Translation file management
- Data Write Standards - Manager CRUD ownership rules
Last Updated: March 2026 (payload-driven overdue steal routing)
🚀 Getting Started
- Home
- Installation
- Migration from KidsChores
- Quick Start
- Quick Start Scenarios
- Dashboard Generation
- Backup & Restore
- OpsCenter
⚙️ Configuration
- General Options
- Points
- Users
- Chores
- Rewards
- Badges - Overview
- Badges - Cumulative
- Badges - Periodic
- Achievements
- Challenges
- Notifications
🔧 Services
💡 Tips & Tricks
- Template Cookbook for Chores, Rewards, and Approvals
- Bulk Chore Updates via Scripts
- Auto-Approve Chores
- Calendar Event Due Dates
- NFC Claim Workflow
- Overdue Penalty Automation
- Critical Overdue Alerts
- Send ChoreOps Alerts to ntfy
📖 Advanced Topics
- Dashboard Integration
- Access Control
- Chores - Advanced
- Badge Cumulative - Advanced
- Badge Periodic - Advanced
📚 Technical Reference
- Points
- Users
- Entities & States
- Chores
- Badges
- Configuration Detail
- Dashboard Generation
- Notifications
- Weekly Activity Reports
👩🔧 Troubleshooting