-
-
Notifications
You must be signed in to change notification settings - Fork 6
Technical: Chores
Audience: automation builders, dashboard authors, and developer-mode users.
Important
This page documents technical contracts (sensor state/attributes, naming behavior, and automation-safe access). Functional setup and business behavior live in Chore Configuration Guide and Chore Advanced Features.
This reference focuses on the two most important chore entities:
sensor.<user>_choreops_choressensor.<user>_choreops_chore_status_<chore>
Both are Home Assistant native entities. Entity IDs and display names are auto-generated, can vary by locale/naming rules, and users can rename entities as needed.
ChoreOps now treats due dates as part of the supported recurrence contract.
-
noneanddailymay omit a due date -
weekly,biweekly,monthly,custom interval,custom from completion, anddaily_multiare expected to have a due date - If a chore should repeat without ever becoming late, use a due date plus
never overdue
This keeps recurrence forecasting, calendar generation, due windows, and approval-boundary behavior anchored to the same schedule source.
- No-due-date
dailychores are supported - For no-due-date
daily,applicable_daysworks as weekday gating - No-due-date chores are excluded from calendar event generation
Existing stored chores from older versions are not automatically deleted or rewritten on load just because they use a now-unsupported combination.
That means an older recurring chore without a due date can still exist after upgrade, but it is considered legacy data rather than a fully supported configuration.
Practical effect:
- The chore can remain in storage after upgrade
- New create/edit/save paths now require a due date for recurrence types outside
noneanddaily - The standalone due-date service now also rejects clearing the due date for those recurrence types
- Calendar and recurrence behavior for those legacy chores should not be relied on until a due date is added
Recommended remediation for existing users:
- Open the chore and add a due date
- If you do not want it to become late, set overdue handling to
never overdue - Save the chore so it is back on the supported scheduling contract
- Entity IDs are now generated by Home Assistant native naming rules and are created with names in local language
- Names can differ across installations and can be renamed by users.
- Stable contract for automations is the exposed state/attribute surface (for example
can_claim,can_approve,claim_button_eid,approve_button_eid,disapprove_button_eid) rather than assumed naming patterns.
Example IDs you may see:
sensor.alex_choreops_choressensor.alex_choreops_chore_status_brush_teeth_ambutton.alex_choreops_chore_disapproval_brush_teeth_am
Aggregated chore statistics for one user (today/week/month/year/all-time + snapshot counters).
- Native state is the all-time approved count used as the sensor value.
- Identity:
purpose,user_name - Stats are exposed with
chore_stat_prefix
High-value attribute groups:
- Current snapshot:
chore_stat_current_due_today,chore_stat_current_claimed,chore_stat_current_approved,chore_stat_current_overdue - Today/Week/Month/Year totals: approved, claimed, missed, completed, points
- All-time totals:
approved_all_time,claimed_all_time,missed_all_time,completed_all_time,points_all_time - Streaks:
chore_stat_longest_streak,chore_stat_longest_missed_streak - Averages:
chore_stat_avg_per_day_week,chore_stat_avg_per_day_month,chore_stat_avg_per_day_year - Top chores:
chore_stat_top_chores_week,chore_stat_top_chores_month,chore_stat_top_chores_year
These map to the rich dashboard rows such as:
- Current Due Today / Current Claimed / Current Approved / Current Overdue
- Approved/Claimed/Missed/Completed/Points across time windows
- Average Per Day (Week/Month/Year)
- Top Chore (Week/Month/Year)
One sensor per user+chore pair with lifecycle state, timing context, actionable flags, and per-chore performance stats.
Operational values include:
-
pending,due,claimed,approved,overdue -
waiting,not_my_turn,missed,completed_by_other -
claimed_in_part,approved_in_part(group/global contexts)
Identity and metadata:
-
purpose,user_name,chore_name,description,assigned_users,labels
Configuration snapshot:
-
default_points,completion_criteria,approval_reset_type,recurring_frequency,applicable_days
Time and availability context:
-
due_date,due_window_start,available_at,time_until_due,time_until_overdue,approval_period_start - Rotation/locks:
global_state,lock_reason,turn_user_name
Actionability and button pointers:
-
can_claim,can_approve -
claim_button_eid,approve_button_eid,disapprove_button_eid
Per-chore performance metrics:
- Counts:
chore_points_earned,chore_claims_count,chore_completed_count,chore_approvals_count,chore_disapproved_count,chore_overdue_count,chore_missed_count - Streaks:
chore_current_streak,chore_longest_streak,chore_current_missed_streak,chore_longest_missed_streak,chore_last_longest_streak_date - Last-event timestamps:
last_claimed,last_approved,last_completed,last_disapproved,last_overdue,chore_last_missed - Attribution:
claimed_by,completed_by
Conditional attributes:
-
custom_frequency_interval,custom_frequency_unit(when recurring frequency is custom) -
chore_approvals_today(for multi-approval reset modes and upon-completion reset)
Use can_claim and can_approve from the status sensor to decide action availability.
Read button IDs from status sensor attributes instead of constructing button entity IDs.
{% set s = 'sensor.alex_choreops_chore_status_brush_teeth_am' %}
{% set can_claim = state_attr(s, 'can_claim') %}
{% set claim_button = state_attr(s, 'claim_button_eid') %}
{{ can_claim and claim_button is not none }}For reusable blueprints or packages, resolve entity IDs from the registry/UI selection, not string concatenation.
Chore state is determined by the interaction of five configuration drivers:
| Driver | Controls | Constants | Engine Method |
|---|---|---|---|
| 1. Completion Criteria | Who must complete (independent, shared, rotation) | COMPLETION_CRITERIA_* |
calculate_transition() |
| 2. Recurring Frequency | How often chore recurs | FREQUENCY_* |
(schedule_engine.py) |
| 3. Approval Reset Type | When approved chores reset to pending | APPROVAL_RESET_* |
should_process_at_boundary() |
| 4. Pending Claim Action | What happens to pending claims at reset | APPROVAL_RESET_PENDING_CLAIM_* |
calculate_boundary_action() |
| 5. Overdue Handling | What happens when due date passes | OVERDUE_HANDLING_* |
calculate_boundary_action() |
State Formula: State = f(CompletionCriteria, Frequency, ApprovalResetType, PendingClaimAction, OverdueHandling)
Use this as the practical interpretation of chore status in dashboards and sensors.
These states are assignee-specific and can differ between users for the same chore:
pendingduewaitingclaimedoverduemissednot_my_turncompletedcompleted_by_other
Notes:
-
completedis the display state for approved work in the current period. -
completed_by_otheris a blocker display state for non-actor assignees in first-claimer modes.
These states summarize the chore across all assigned users:
pendingduewaitingclaimedcompletedcompleted_in_partoverduemissedindependentclaimed_in_part
Important mapping rule:
- Persisted partial state
approved_in_partis published as global UI statecompleted_in_part.
How to reason about mismatches:
- Stored workflow state tracks checkpoints (
approved,approved_in_part). - Display state is user-facing projection (
completed,completed_in_part). - This means stored and displayed labels can intentionally differ while still representing the same lifecycle outcome.
Chore state changes occur at two distinct boundaries:
- Triggers: claim, approve, disapprove, undo actions
- Protection: asyncio.Lock per (assignee_id, chore_id) prevents race conditions
- Processing: Immediate state transition via ChoreEngine
-
Location:
chore_manager.py_claim_chore_locked(),_approve_chore_locked(), etc.
- Triggers: midnight_rollover, periodic_update (every ~5 min)
- Processing Order (Phase 1): Reset-Before-Overdue (prevents Gremlin #1)
- Batching: Single persist at end of pipeline (Phase 1)
-
Location:
chore_manager.py_on_midnight_rollover(),_on_periodic_update()
Invariant 1: Single State Per Tick
- Each (assignee_id, chore_id) pair modified at most once per pipeline run
- Enforced by: Set-based exclusion (Phase 1) + debug tracking (Phase 4)
- Debug flag:
const.DEBUG_PIPELINE_GUARDS
Invariant 2: Idempotent Processing
- Running same scan twice produces same result
-
_process_overdue()skips if already OVERDUE (Phase 4) -
_process_approval_reset_entries()checks current state before transitioning
Invariant 3: Persist-Once-Per-Batch
- All state changes batched, then single
_persist()call - Reduces SD card writes from O(n) to O(1)
- Implementation:
persist=Falseparameter in processing methods
Valid Configurations:
-
UPON_COMPLETION+ any frequency → Resets immediately on approval -
AT_MIDNIGHT_ONCE+FREQUENCY_DAILY→ Classic daily chore -
AT_DUE_DATE_*+FREQUENCY_WEEKLY→ Due date triggers reset -
MANUAL+ any frequency → Never auto-resets (Phase 3)
Gremlin Scenarios (Prevented by Pipeline Reorder):
-
Overdue-After-Approval: Chore approved at midnight → reset to PENDING → immediately OVERDUE
- Prevention: Reset processes BEFORE overdue check
-
Double-Processing: Chore in both reset AND overdue lists
- Prevention: Set-based exclusion filters overdue list after reset
-
Non-Recurring Past Due:
FREQUENCY_NONEchore approved after due date → reschedules → goes OVERDUE- Prevention: Clear due date on UPON_COMPLETION for non-recurring chores
- In Developer Tools → States, confirm expected chore sensors exist for the target user profile.
- Verify
purposeto ensure you are reading the intended sensor contract. - If action buttons do not work, inspect
claim_button_eid/approve_button_eid/disapprove_button_eidfirst. - If timing appears wrong, inspect
due_date,due_window_start,available_at,time_until_due, andtime_until_overdueon the status sensor.
- Sensor implementations:
custom_components/choreops/sensor.py - Attribute and key constants:
custom_components/choreops/const.py - User-visible names/states:
custom_components/choreops/translations/en.json
🚀 Getting Started
- Home
- Installation
- Migration from KidsChores
- Quick Start
- Quick Start Scenarios
- Dashboard Generation
- Backup & Restore
⚙️ 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
- Auto-Approve Chores
- Calendar Event Due Dates
- NFC Claim Workflow
- Overdue Penalty Automation
- Critical Overdue Alerts
📖 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