Releases: tempus2016/taskmate
v2.4.0-beta1
Test new points card
v2.3.0
TaskMate v2.3.0
Internationalisation (i18n)
TaskMate is now fully translatable. Every user-facing string — the backend config flow, options menus, select options, service descriptions, and all 14 Lovelace cards — supports translation.
Frontend (Lovelace cards):
- New
taskmate-localize.jsmodule loaded globally — detects language fromhass.language, fetches the matching locale file, and falls back to English - Language fallback chain with caching:
en-GB→en-GB.json,pt-BR→pt.json→en-GB.json - 372 translation keys across all 14 cards with
{placeholder}substitution for dynamic values
Backend (HA integration):
- Config flow setup wizard fully translated
- Options flow menus translated — main menu via HA's native system, sub-menus via runtime translation lookup
- All select option labels (time categories, days of week, schedule modes, recurrence intervals, streak modes, action buttons) translated via
translation_key - All 14 service descriptions translated in Developer Tools
Included languages:
| Language | Frontend | Backend |
|---|---|---|
| English | en-GB.json |
en.json, en-GB.json |
| Norwegian Bokmål | nb.json |
nb.json |
| Norwegian Nynorsk | nn.json |
nn.json |
| Portuguese | pt.json |
pt.json, pt-BR.json |
Adding a new language:
- Copy
www/locales/en-GB.json→www/locales/<lang>.json(372 keys) - Copy
translations/en.json→translations/<lang>.json - Translate the values, keep all keys unchanged
- Restart HA — the new language loads automatically
Bug Fixes
Chore Completion & Approval
- Reject fully reverses awards — rejecting an auto-approved chore now correctly reverses points,
total_points_earned,total_chores_completed, and streak. Previously only base points were deducted. - Points awarded includes weekend bonus —
completion.points_awardednow stores the full amount (base + weekend multiplier) so reject reverses the correct total. - Perfect week counts pending completions — children no longer miss the perfect week bonus because a parent hasn't approved yet.
- Streak uses completion date — approving a Saturday chore on Monday correctly records the streak against Saturday, not Monday.
- Warnings on missing approval IDs —
async_approve_choreandasync_approve_rewardnow log a warning instead of silently returning when an ID isn't found.
Rewards
- Reward deletion cleans up claims —
async_remove_rewardnow removes pending claims for the deleted reward, preventing orphaned data and errors. - Committed points race condition fixed — the pending-claims loop in
async_claim_rewardnow fetches each reward once per iteration, eliminating the double-lookup TOCTOU. - ClaimRewardButton availability — subtracts committed points from pending claims when determining if the button should be enabled.
Data Integrity
- Mutable list aliasing fixed —
Child.from_dict,Chore.from_dict,Reward.from_dict, andPenalty.from_dictnow copy lists withlist()instead of sharing references with storage, preventing in-place mutations from bypassing the update path. - Points name/icon preserved on restart — uses a
_initial_setup_doneflag instead of comparing against default values. Deliberately choosing "Stars" as a points name no longer gets overwritten.
Approvals Card
- Works with either entity — accepts both
sensor.pending_approvals(readschore_completions) andsensor.taskmate_overview(readstodays_completions, filters unapproved). Previously showed "All caught up!" when pointed at the overview sensor.
Buttons & Sensors
- Buttons update dynamically — new chores, rewards, or children added after setup get button entities without requiring a restart.
- Class rename —
ChoremandorOverallStatsSensor→TaskMateOverallStatsSensor(internal only, no entity ID change). - Sensor attributes cached — overview sensor's
extra_state_attributescached per coordinator refresh, avoiding O(children × chores) recomputation on every HA poll.
Services
- 6 missing service definitions —
preview_sound,set_chore_order,add_penalty,update_penalty,remove_penalty,apply_penaltynow appear in Developer Tools with descriptions and field documentation.
Code Quality
- Penalty imports consolidated at module level in
storage.pyandcoordinator.py - Deprecated
event_looptest fixture removed;asyncio_mode = autoinpytest.ini - Voluptuous no longer mocked in tests — real schema validation runs
- All 120 tests pass
v2.3.0-beta4
TaskMate v2.3.0-beta.4 — Release Notes
Full Internationalisation (i18n)
TaskMate is now fully translatable — backend config flow, options flow, services, select options, and all 14 Lovelace cards.
Frontend (Lovelace cards):
taskmate-localize.jsmodule — detectshass.language, fetches matching locale, falls back toen-GB- Language fallback chain:
nb→nb.json,en-GB→en-GB.json,pt-BR→pt.json→en-GB.json - Failed locale fetches cached to prevent 404 spam
- 372 translation keys across all 14 cards
{placeholder}substitution for dynamic values
Backend (HA integration):
- Config flow setup wizard fully translated
- Options flow menus translated — main menu uses HA's native translation system, sub-menus use runtime translation lookup
- All select option labels (time categories, days, schedule modes, recurrence, actions, streak modes) translated via
translation_key+selectorsection instrings.json - Service descriptions in Developer Tools fully translated
Included languages:
| Language | Frontend (www/locales/) |
Backend (translations/) |
|---|---|---|
| English | en-GB.json (372 keys) |
en.json |
| Norwegian Bokmål | nb.json |
nb.json |
| Norwegian Nynorsk | nn.json |
nn.json |
| Portuguese | pt.json |
pt.json, pt-BR.json |
Adding a new language:
- Copy
www/locales/en-GB.json→www/locales/<lang>.json - Copy
translations/en.json→translations/<lang>.json - Translate the values (keep keys as-is)
- Restart HA — cards and config UI load the new language automatically
Changes since beta.02
i18n — Config flow select options (new)
- All
SelectOptionDictlabels replaced withtranslation_key+ plain string values - 10 translation keys added to
selectorsection:child_action,chore_action,reward_action,time_category,schedule_mode,due_days_option,recurrence,recurrence_day_option,first_occurrence_mode,streak_reset_mode - Days of week, time categories, recurrence labels, action buttons (Save/Delete), streak modes — all now translate in the HA settings UI
i18n — Config flow menus (new)
- Main settings menu (
init) now passes a list toasync_show_menuso HA translates labels natively - Sub-menus (manage children/chores/rewards) use
_get_translation()runtime helper to look up "Add New Child", "Back to Main Menu" etc. from translation files - Dynamic menu entries (child/chore/reward names) simplified — removed "Edit: " prefix that couldn't be translated
i18n — JS card title fallbacks (new)
- Parent Dashboard, Reorder, and Points cards now use
_t()fallback for default titles in render (previously hardcoded insetConfig) - Leaderboard "TIE" label moved from CSS
content:pseudo-element to translatable DOM<span>with_t('leaderboard.tie')
i18n — Localize module fixes (new)
- Fallback language changed from
entoen-GB(matching actual source locale file) - Language fallback chain:
en-GB→ triesen-GB.json,pt-BR→ triespt-BR.json→pt.json - Failed fetches cached as
null— stops 404 retry spam on every render cycle
Approvals card fix (new)
- Card now works with both
sensor.pending_approvals(readschore_completions) andsensor.taskmate_overview(readstodays_completions, filters to unapproved) - Previously showed "All caught up!" when pointed at the overview sensor
Bug Fixes (from beta.01)
Chore Completion & Approval
- Reject now fully reverses awards (points, total_points_earned, total_chores_completed, streak)
- Points awarded includes weekend bonus — stored in
completion.points_awardedfor correct reversal - Perfect week check counts pending completions (not just approved)
- Streak uses completion date, not approval date
- Approve/reject log warnings on missing IDs
Rewards
- Deleting a reward cleans up pending claims (
remove_reward_claims_for_reward) - Committed points TOCTOU fixed — single fetch per reward in pending-claims loop
- ClaimRewardButton subtracts committed points for accurate availability
Data Integrity
- Mutable list aliasing fixed in all
from_dictmethods - Points name/icon no longer overwritten on restart
Buttons & Sensors
- Buttons update dynamically for new children/chores/rewards
- Renamed
ChoremandorOverallStatsSensor→TaskMateOverallStatsSensor - Sensor attributes cached per coordinator refresh
Services
- 6 missing service definitions added (preview_sound, set_chore_order, add/update/remove/apply_penalty)
Code Quality
- Penalty imports consolidated at module level
- Deprecated
event_looptest fixture removed - Voluptuous no longer mocked in tests
Files Changed (28 modified, 12+ new)
| Area | Files |
|---|---|
| i18n module | www/taskmate-localize.js (new) |
| Frontend locales | www/locales/en-GB.json, nb.json, nn.json, pt.json (new) |
| Backend translations | translations/nb.json, nn.json, pt.json, pt-BR.json (new) |
| Frontend cards | 14 JS files — _t() calls, title fallbacks, TIE label fix |
| Approvals card | taskmate-approvals-card.js — dual-entity support |
| Config flow | config_flow.py — translation_key selectors, list menus, _get_translation() helper |
| Frontend loader | frontend.py — register localize module |
| Translation source | strings.json — selector section + 6 new services |
| Backend fixes | __init__.py, coordinator.py, models.py, storage.py, button.py, sensor.py |
| Tests | conftest.py, pytest.ini |
| Version | manifest.json → 2.3.0-beta.03 |
v2.3.0-beta3
TaskMate v2.3.0-beta.3 — Release Notes
Full Internationalisation (i18n)
TaskMate is now fully translatable — backend config flow, options flow, services, select options, and all 14 Lovelace cards.
Frontend (Lovelace cards):
taskmate-localize.jsmodule — detectshass.language, fetches matching locale, falls back toen-GB- Language fallback chain:
nb→nb.json,en-GB→en-GB.json,pt-BR→pt.json→en-GB.json - Failed locale fetches cached to prevent 404 spam
- 372 translation keys across all 14 cards
{placeholder}substitution for dynamic values
Backend (HA integration):
- Config flow setup wizard fully translated
- Options flow menus translated — main menu uses HA's native translation system, sub-menus use runtime translation lookup
- All select option labels (time categories, days, schedule modes, recurrence, actions, streak modes) translated via
translation_key+selectorsection instrings.json - Service descriptions in Developer Tools fully translated
Included languages:
| Language | Frontend (www/locales/) |
Backend (translations/) |
|---|---|---|
| English | en-GB.json (372 keys) |
en.json |
| Norwegian Bokmål | nb.json |
nb.json |
| Norwegian Nynorsk | nn.json |
nn.json |
| Portuguese | pt.json |
pt.json, pt-BR.json |
Adding a new language:
- Copy
www/locales/en-GB.json→www/locales/<lang>.json - Copy
translations/en.json→translations/<lang>.json - Translate the values (keep keys as-is)
- Restart HA — cards and config UI load the new language automatically
Changes since beta.02
i18n — Config flow select options (new)
- All
SelectOptionDictlabels replaced withtranslation_key+ plain string values - 10 translation keys added to
selectorsection:child_action,chore_action,reward_action,time_category,schedule_mode,due_days_option,recurrence,recurrence_day_option,first_occurrence_mode,streak_reset_mode - Days of week, time categories, recurrence labels, action buttons (Save/Delete), streak modes — all now translate in the HA settings UI
i18n — Config flow menus (new)
- Main settings menu (
init) now passes a list toasync_show_menuso HA translates labels natively - Sub-menus (manage children/chores/rewards) use
_get_translation()runtime helper to look up "Add New Child", "Back to Main Menu" etc. from translation files - Dynamic menu entries (child/chore/reward names) simplified — removed "Edit: " prefix that couldn't be translated
i18n — JS card title fallbacks (new)
- Parent Dashboard, Reorder, and Points cards now use
_t()fallback for default titles in render (previously hardcoded insetConfig) - Leaderboard "TIE" label moved from CSS
content:pseudo-element to translatable DOM<span>with_t('leaderboard.tie')
i18n — Localize module fixes (new)
- Fallback language changed from
entoen-GB(matching actual source locale file) - Language fallback chain:
en-GB→ triesen-GB.json,pt-BR→ triespt-BR.json→pt.json - Failed fetches cached as
null— stops 404 retry spam on every render cycle
Approvals card fix (new)
- Card now works with both
sensor.pending_approvals(readschore_completions) andsensor.taskmate_overview(readstodays_completions, filters to unapproved) - Previously showed "All caught up!" when pointed at the overview sensor
Bug Fixes (from beta.01)
Chore Completion & Approval
- Reject now fully reverses awards (points, total_points_earned, total_chores_completed, streak)
- Points awarded includes weekend bonus — stored in
completion.points_awardedfor correct reversal - Perfect week check counts pending completions (not just approved)
- Streak uses completion date, not approval date
- Approve/reject log warnings on missing IDs
Rewards
- Deleting a reward cleans up pending claims (
remove_reward_claims_for_reward) - Committed points TOCTOU fixed — single fetch per reward in pending-claims loop
- ClaimRewardButton subtracts committed points for accurate availability
Data Integrity
- Mutable list aliasing fixed in all
from_dictmethods - Points name/icon no longer overwritten on restart
Buttons & Sensors
- Buttons update dynamically for new children/chores/rewards
- Renamed
ChoremandorOverallStatsSensor→TaskMateOverallStatsSensor - Sensor attributes cached per coordinator refresh
Services
- 6 missing service definitions added (preview_sound, set_chore_order, add/update/remove/apply_penalty)
Code Quality
- Penalty imports consolidated at module level
- Deprecated
event_looptest fixture removed - Voluptuous no longer mocked in tests
Files Changed (28 modified, 12+ new)
| Area | Files |
|---|---|
| i18n module | www/taskmate-localize.js (new) |
| Frontend locales | www/locales/en-GB.json, nb.json, nn.json, pt.json (new) |
| Backend translations | translations/nb.json, nn.json, pt.json, pt-BR.json (new) |
| Frontend cards | 14 JS files — _t() calls, title fallbacks, TIE label fix |
| Approvals card | taskmate-approvals-card.js — dual-entity support |
| Config flow | config_flow.py — translation_key selectors, list menus, _get_translation() helper |
| Frontend loader | frontend.py — register localize module |
| Translation source | strings.json — selector section + 6 new services |
| Backend fixes | __init__.py, coordinator.py, models.py, storage.py, button.py, sensor.py |
| Tests | conftest.py, pytest.ini |
| Version | manifest.json → 2.3.0-beta.03 |
v2.3.0-b2
TaskMate v2.3.0-beta.2 — Release Notes
Full Internationalisation (i18n)
TaskMate is now fully translatable — both the backend (config flow, options, services) and all 14 Lovelace cards.
Frontend (Lovelace cards):
- New
taskmate-localize.jsmodule loaded globally — detects language fromhass.language, fetches the matching locale file, falls back toen-GB - 371 translation keys extracted from 14 JS cards into
www/locales/JSON files - Language fallback chain:
en-GB→en→ key (handles regional variants likeen-GBwithout needing a separate file for every variant) - Failed locale fetches are cached to prevent 404 spam on every render cycle
{placeholder}substitution for dynamic values (names, counts, points)
Backend (HA integration):
translations/folder now contains full translations for config flow, options flow (manage children/chores/rewards/settings), and all 14 service descriptions
Included languages:
| Language | Frontend (www/locales/) |
Backend (translations/) |
|---|---|---|
| English | en-GB.json (371 keys) |
en.json |
| Norwegian Bokmål | nb.json |
nb.json |
| Norwegian Nynorsk | nn.json |
nn.json |
| Portuguese | pt.json |
pt.json |
Adding a new language:
- Copy
www/locales/en-GB.json→www/locales/<lang>.json - Copy
translations/en.json→translations/<lang>.json - Translate the values (keep keys as-is)
- Restart HA — cards and config UI load the new language automatically
Bug Fixes
Chore Completion & Approval
- Reject now fully reverses awards — rejecting an auto-approved chore correctly undoes points,
total_points_earned,total_chores_completed, and streak. Previously only base points were deducted. - Points awarded now includes weekend bonus —
completion.points_awardedstores the full amount (base + weekend multiplier), so reject reverses the correct total. - Perfect week check counts pending completions — children no longer miss the perfect week bonus just because a parent hasn't approved yet.
- Streak uses completion date, not approval date — approving a Saturday chore on Monday now correctly records the streak against Saturday.
- Approve/reject log warnings on missing IDs —
async_approve_choreandasync_approve_rewardnow log a warning instead of silently doing nothing when a completion or claim ID isn't found.
Rewards
- Deleting a reward cleans up pending claims — added
remove_reward_claims_for_reward()to storage, called fromasync_remove_reward. Previously, deleting a reward left orphaned claims causing errors. - Committed points TOCTOU fixed — the pending-claims loop in
async_claim_rewardnow fetches each reward once per iteration, eliminating the race condition. - ClaimRewardButton shows correct availability — the button now subtracts committed points from pending claims when determining if it should be enabled.
Data Integrity
- Mutable list aliasing fixed —
from_dictmethods now copy lists instead of sharing references with storage, preventing in-place mutations from bypassing the update path. - Points name/icon no longer overwritten on restart — uses a
_initial_setup_doneflag instead of comparing against default values.
Buttons & Sensors
- Buttons update dynamically — new chores, rewards, or children added after initial setup now get corresponding button entities without requiring a restart.
- Renamed
ChoremandorOverallStatsSensortoTaskMateOverallStatsSensor(class name only — no entity ID change). - Sensor attributes cached —
extra_state_attributeson the overview sensor is now cached per coordinator refresh, avoiding expensive recomputation on every HA poll.
Services
- 6 missing service definitions added —
preview_sound,set_chore_order,add_penalty,update_penalty,remove_penalty, andapply_penaltynow have proper entries inservices.yamlandstrings.json.
Code Quality
- Penalty imports consolidated at module level in
storage.pyandcoordinator.py. - Deprecated
event_loopfixture removed from tests; addedasyncio_mode = auto. - Voluptuous no longer mocked in tests — real schema validation now runs.
Files Changed (27 modified, 9 new)
| Area | Files |
|---|---|
| i18n module | www/taskmate-localize.js (new) |
| Frontend locales | www/locales/en-GB.json, nb.json, nn.json, pt.json (new) |
| Backend translations | translations/nb.json, nn.json, pt.json (new) |
| Frontend cards | 14 JS files — hardcoded strings → _t() calls |
| Frontend loader | frontend.py — register localize module |
| Backend fixes | __init__.py, coordinator.py, models.py, storage.py, button.py, sensor.py |
| Services | services.yaml, strings.json, translations/en.json |
| Tests | conftest.py, pytest.ini |
| Version | manifest.json → 2.3.0-beta.02 |
2.3.0-beta.1
TaskMate v2.3.0-beta-01 — Release Notes
Internationalisation (i18n)
TaskMate is now fully translatable. Every user-facing string across all 14 Lovelace cards has been extracted into locale files, and the integration automatically loads the correct language based on your Home Assistant language setting.
How it works:
- A lightweight
taskmate-localize.jsmodule detects your HA language and loads the matching locale file - Falls back to English for any missing translations
- Supports
{placeholder}substitution for dynamic values (names, counts, etc.)
Included languages:
- English (
en.json) — 371 translation keys - Norwegian Bokmål (
nb.json) - Norwegian Nynorsk (
nn.json)
Adding your own language:
- Copy
www/locales/en.jsontowww/locales/<lang>.json(e.g.de.jsonfor German) - Translate the values (keep the keys as-is)
- Set your HA language — TaskMate picks it up automatically
Backend translations (strings.json, translations/en.json) are also updated and synced.
Bug Fixes
Chore Completion & Approval
- Reject now fully reverses awards — rejecting an auto-approved chore correctly undoes points,
total_points_earned,total_chores_completed, and streak. Previously only base points were deducted. - Points awarded now includes weekend bonus —
completion.points_awardedstores the full amount (base + weekend multiplier), so reject reverses the correct total. - Perfect week check counts pending completions — children no longer miss the perfect week bonus just because a parent hasn't approved yet.
- Streak uses completion date, not approval date — approving a Saturday chore on Monday now correctly records the streak against Saturday.
- Approve/reject log warnings on missing IDs —
async_approve_choreandasync_approve_rewardnow log a warning instead of silently doing nothing when a completion or claim ID isn't found.
Rewards
- Deleting a reward cleans up pending claims — added
remove_reward_claims_for_reward()to storage, called fromasync_remove_reward. Previously, deleting a reward left orphaned claims causing errors. - Committed points TOCTOU fixed — the pending-claims loop in
async_claim_rewardnow fetches each reward once per iteration, eliminating the race condition. - ClaimRewardButton shows correct availability — the button now subtracts committed points from pending claims when determining if it should be enabled. Previously it showed as available even when the claim would fail.
Data Integrity
- Mutable list aliasing fixed —
Child.from_dict,Chore.from_dict,Reward.from_dict, andPenalty.from_dictnow copy lists instead of sharing references with storage. This prevents in-place mutations (.remove(),.append()) from bypassing the update path. - Points name/icon no longer overwritten on restart — the initial setup check now uses a
_initial_setup_doneflag instead of comparing against default values. Users who deliberately chose "Stars" as their points name will no longer have it overwritten.
Buttons & Sensors
- Buttons update dynamically — new chores, rewards, or children added after initial setup now get corresponding button entities without requiring a restart.
- Renamed
ChoremandorOverallStatsSensortoTaskMateOverallStatsSensor(class name only — no entity ID change). - Sensor attributes cached —
extra_state_attributeson the overview sensor is now cached per coordinator refresh, avoiding expensive O(children × chores) recomputation on every HA poll.
Services
- 6 missing service definitions added —
preview_sound,set_chore_order,add_penalty,update_penalty,remove_penalty, andapply_penaltynow have proper entries inservices.yamlandstrings.json, so they appear correctly in Developer Tools.
Code Quality
- Penalty imports consolidated —
Penaltyis now imported at module level instorage.pyandcoordinator.pyinstead of using late imports inside methods. - Deprecated
event_loopfixture removed from test conftest; addedasyncio_mode = autotopytest.ini. - Voluptuous no longer mocked in tests — real schema validation now runs, catching schema bugs that were previously masked.
Files Changed
| Area | Files | Changes |
|---|---|---|
| i18n module | www/taskmate-localize.js |
New |
| Locale files | www/locales/en.json, nb.json, nn.json |
New (371 keys each) |
| Frontend cards | 14 JS files | _t() calls replacing hardcoded strings |
| Frontend loader | frontend.py |
Register localize module |
| Backend | __init__.py, coordinator.py, models.py, storage.py, button.py, sensor.py |
Bug fixes |
| Services | services.yaml, strings.json, translations/en.json |
6 new service definitions |
| Tests | conftest.py, pytest.ini |
Fixture + asyncio mode fix |
v2.2.0
TaskMate v2.2.0 — Bug Fixes & Data Integrity
This release addresses critical data integrity issues, race conditions in the reward workflow, a security hardening for notification services, and numerous quality-of-life improvements across storage, configuration, and entity management.
Critical Fixes
Longer unique IDs to prevent collisions
IDs generated for children, chores, rewards, completions, and claims are now 16 hex characters (64 bits of entropy), up from 8 characters (32 bits). The previous length had a realistic collision probability around ~300 items due to the birthday paradox, which could silently overwrite data or misroute points.
Existing IDs are not affected — this change only applies to newly created items.
Reward claim race condition resolved
Previously, a child could submit multiple reward claims simultaneously, each passing the points check independently, leading to over-spending when all were approved. The claim flow now calculates committed points from all pending (unapproved) claims before checking affordability.
Double-approve guard on reward claims
async_approve_reward now checks if a claim is already approved and returns early, preventing points from being deducted twice if two approve calls arrive concurrently.
Notification service restricted to notify domain
The notify_service setting previously accepted any domain.service string and passed it directly to hass.services.async_call(). It is now restricted to the notify domain only. Non-notify services are logged as a warning and ignored. The call also uses await instead of fire-and-forget async_create_task, so errors are properly caught and logged.
Data Integrity Improvements
Orphaned data cleanup on child removal
Removing a child now also cleans up:
- All chore completions for that child
- All reward claims for that child
- All points transactions for that child
- All
last_completedrecurrence records for that child - The child's ID from any chore
assigned_tolists
Orphaned data cleanup on chore removal
Removing a chore now also cleans up:
- All completions for that chore
- All
last_completedrecurrence records for that chore - The chore's ID from any child's
chore_orderlist
History pruning uses proper storage API
async_prune_history no longer mutates storage._data["completions"] directly. It now uses the new storage.replace_completions() method, maintaining proper encapsulation.
Configuration & Settings Fixes
Settings no longer overwritten on restart
Previously, points_name and points_icon from the initial config entry were unconditionally written to storage on every Home Assistant restart, overwriting any changes made via the options flow. Settings are now only applied from the config entry when storage still holds the defaults.
Settings form batches saves
The settings form previously triggered 8 sequential save + refresh cycles when saving. All settings are now batched into a single write and refresh, eliminating unnecessary I/O and potential UI flicker.
Config flow __getattr__ validates IDs
The dynamic step routing for edit_child/edit_chore/edit_reward now validates that the extracted ID exists in storage before routing. Previously, any attribute access matching the naming pattern would silently set an invalid ID.
Model & Type Improvements
Proper list defaults on data models
Child.streak_milestones_achievedandChild.awarded_perfect_weeksnow usefield(default_factory=list)instead of defaulting toNone, eliminating the need foror []guards throughout the codebase.Penalty.assigned_tonow useslist[str]withfield(default_factory=list)instead of barelist = None.
Unused import removed
Removed an unused from .models import Penalty import in handle_update_penalty.
Frontend
Safer Lovelace resource loading
The frontend resource loader no longer mutates the internal resources.loaded attribute. It now calls async_load() unconditionally, reducing coupling to Home Assistant internals.
Missed time-of-day chores
Chores assigned to Morning / Afternoon / Evening / Night now dim and become non-interactive once that time window has passed without completion. Controlled by elapsed_time_mode: dim | hide | show on the child card (default: dim). Chores set to Anytime are never affected. Already-completed chores keep their green done style.
New Storage Methods
The following methods were added to TaskMateStorage to support proper data cleanup:
| Method | Purpose |
|---|---|
replace_completions(completions) |
Replace all completions (used by history pruning) |
remove_completions_for_child(child_id) |
Remove all completions for a child |
remove_completions_for_chore(chore_id) |
Remove all completions for a chore |
remove_reward_claims_for_child(child_id) |
Remove all reward claims for a child |
remove_transactions_for_child(child_id) |
Remove all transactions for a child |
remove_last_completed_for_child(child_id) |
Remove recurrence records for a child |
remove_last_completed_for_chore(chore_id) |
Remove recurrence records for a chore |
Tests
All 120 tests pass. Test updates:
- Prune history test updated to work with the new
replace_completionsAPI - Model tests updated to reflect proper list defaults (no longer testing
Nonepassthrough)
Upgrade Notes
- No breaking changes. All existing data and configurations are preserved.
- Existing short IDs (8 characters) continue to work. Only new items get 16-character IDs.
- If you previously set
notify_serviceto a non-notify domain (e.g.,automation.trigger), it will now be ignored with a warning log. Update it to a validnotify.*service.
Full Changelog
Files changed:
custom_components/taskmate/models.pycustom_components/taskmate/coordinator.pycustom_components/taskmate/storage.pycustom_components/taskmate/__init__.pycustom_components/taskmate/config_flow.pycustom_components/taskmate/frontend.pytests/test_coordinator_logic.pytests/test_models.py
v2.1.0
TaskMate v2.1.0
What's New
Penalty System
The flip side of rewards — deduct points for unwanted behaviour without having to guess an amount each time.
Create named penalties (e.g. "Not going to bed", "Too much screen time", "Talking back") with a fixed point deduction, then apply them to a child with a single tap. The deduction is logged in the activity feed so you always have a record.
New taskmate-penalties-card
- Child selector tabs at the top (hidden when there's only one child)
- Each penalty shows its icon, name, and point cost in a red badge
- Tap Apply → points deducted instantly, tile flashes red, toast confirms the action
- Toggle edit mode (pencil icon) to add, rename, or delete penalties
4 new services for automation / scripting
| Service | Description |
|---|---|
taskmate.add_penalty |
Create a new penalty definition |
taskmate.update_penalty |
Update an existing penalty's name, points, or icon |
taskmate.remove_penalty |
Delete a penalty definition |
taskmate.apply_penalty |
Apply a penalty to a child (deducts points immediately) |
Example:
service: taskmate.apply_penalty
data:
penalty_id: abc12345
child_id: a8c8376aBug Fixes
-
Crash deleting a chore — The config flow called a non-existent method (
async_delete_chore) instead of the correctasync_remove_chore. Deleting a chore from Settings now works correctly. -
Crash when settings contain invalid values — If a setting like
weekend_multiplierorperfect_week_bonuswas somehow saved as a non-numeric string,float()/int()would throw and take the entire sensor offline. These conversions now fall back to their defaults gracefully. -
Crash in chore availability check —
is_chore_available_for_childcaughtValueErrorwhen parsing a stored date string, but notTypeError. If the stored value wasNoneor a non-string, slicing it raised an unhandledTypeError. Fixed to catch both. -
Reward rejection bypassed storage API —
async_reject_rewardwas directly writing tostorage._data["reward_claims"]instead of going through the storage layer. Addedremove_reward_claim()toTaskMateStorageand updated the coordinator to use it. -
Double dict lookup for child names — A fragile
a and b or cpattern was used to look up the same child dict key twice in the sensor. Replaced with a clean single lookup.
Upgrade Notes
No migration needed. Penalties are stored in a new penalties key in the TaskMate data store — existing data is untouched.
After upgrading, hard-refresh your browser (Cmd+Shift+R / Ctrl+Shift+R) to load the new card JavaScript.
v2.0.0
TaskMate v2.0.0 — Chore Scheduling & Simplified Rewards
This is a major release. It introduces a full chore recurrence system, removes the smart reward pricing engine in favour of simple fixed costs, and includes several bug fixes and stability improvements.
⚠️ Breaking Changes
Smart Reward Pricing Removed
Dynamic reward pricing has been removed entirely. All reward costs are now fixed values set by the parent.
What this means for existing installations:
- Any reward that used dynamic pricing will retain whatever cost was last calculated — this becomes the new fixed cost. Review your rewards after upgrading and adjust costs if needed.
- The Days to Goal, Override Point Value, and Completion % Per Month fields no longer exist.
- Reward costs are now simply: set a number, that's the cost.
completion_percentage_per_month Removed from Chores
This field has been removed from the chore model. It is no longer stored, exposed in the sensor, or accepted in the config flow. Existing chore data is migrated automatically on first startup — the field is silently stripped.
🆕 Chore Scheduling — Two Modes
Chores now have a Scheduling Mode which determines how they appear and when they can be completed.
Mode A — Specific Days
The existing behaviour. Choose which days of the week the chore appears on the child card. Leave empty to show every day.
Schedule Mode: Specific days of the week
Due Days: Monday, Wednesday, Friday
Mode B — Recurring
The chore has a rolling recurrence window. Once completed, it is not available again until the window expires.
| Recurrence | Window |
|---|---|
| Every 2 days | 2 days from last completion date |
| Weekly | 7 days from last completion date |
| Every 2 weeks | 14 days from last completion date |
| Monthly | 30 days from last completion date |
| Every 3 months | 90 days from last completion date |
| Every 6 months | 180 days from last completion date |
type: custom:taskmate-child-card
entity: sensor.taskmate_overview
child_id: a8c8376a
recurrence_done_mode: dim
Configurable in the card visual editor.
🆕 Last Completed Store
A new lightweight store tracks the two most recent completion timestamps per chore per child, separately from the prunable completion history. This is what drives recurrence window checking and is never pruned regardless of the history_days setting.
Undo behaviour: Undoing a completion restores the previous completion as the window anchor — a child can't claiam a weekly chore by repeatedly completing and undoing.
🐛 Bug Fixes
Child Card — notAvailableRecurrence Error
The variable used to apply the recurrence dim/hide state was defined in the filter scope but referenced in the render method — causing a ReferenceError that prevented the child card from rendering. Fixed.
Reward Pricing — Static Cost Now Consistent
async_claim_reward and async_approve_reward were still calling the removed dynamic pricing method. Both now use reward.cost directly.
📋 Files Changed
Backend: models.py · storage.py · coordinator.py · sensor.py · button.py · config_flow.py · const.py · strings.json · translations/en.json
Frontend: www/taskmate-child-card.js · www/taskmate-rewards-card.js · www/taskmate-overview-card.js · www/taskmate-parent-dashboard-card.js
⬆️ Upgrading
- Deploy all files to
/config/custom_components/taskmate/ - Restart Home Assistant
- Review your rewards — check that costs are correct after the dynamic pricing removal
- Existing chores default to Specific Days scheduling — no action needed unless you want to convert any to Recurring
v2.0.0-beta-01
Beta testing a new scoring system.