Skip to content

Releases: tempus2016/taskmate

v2.4.0-beta1

31 Mar 19:16

Choose a tag to compare

v2.4.0-beta1 Pre-release
Pre-release

Test new points card

v2.3.0

31 Mar 12:55

Choose a tag to compare

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.js module loaded globally — detects language from hass.language, fetches the matching locale file, and falls back to English
  • Language fallback chain with caching: en-GBen-GB.json, pt-BRpt.jsonen-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:

  1. Copy www/locales/en-GB.jsonwww/locales/<lang>.json (372 keys)
  2. Copy translations/en.jsontranslations/<lang>.json
  3. Translate the values, keep all keys unchanged
  4. 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 bonuscompletion.points_awarded now 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 IDsasync_approve_chore and async_approve_reward now log a warning instead of silently returning when an ID isn't found.

Rewards

  • Reward deletion cleans up claimsasync_remove_reward now removes pending claims for the deleted reward, preventing orphaned data and errors.
  • Committed points race condition fixed — the pending-claims loop in async_claim_reward now 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 fixedChild.from_dict, Chore.from_dict, Reward.from_dict, and Penalty.from_dict now copy lists with list() 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_done flag 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 (reads chore_completions) and sensor.taskmate_overview (reads todays_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 renameChoremandorOverallStatsSensorTaskMateOverallStatsSensor (internal only, no entity ID change).
  • Sensor attributes cached — overview sensor's extra_state_attributes cached per coordinator refresh, avoiding O(children × chores) recomputation on every HA poll.

Services

  • 6 missing service definitionspreview_sound, set_chore_order, add_penalty, update_penalty, remove_penalty, apply_penalty now appear in Developer Tools with descriptions and field documentation.

Code Quality

  • Penalty imports consolidated at module level in storage.py and coordinator.py
  • Deprecated event_loop test fixture removed; asyncio_mode = auto in pytest.ini
  • Voluptuous no longer mocked in tests — real schema validation runs
  • All 120 tests pass

v2.3.0-beta4

31 Mar 12:30

Choose a tag to compare

v2.3.0-beta4 Pre-release
Pre-release

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.js module — detects hass.language, fetches matching locale, falls back to en-GB
  • Language fallback chain: nbnb.json, en-GBen-GB.json, pt-BRpt.jsonen-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 + selector section in strings.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:

  1. Copy www/locales/en-GB.jsonwww/locales/<lang>.json
  2. Copy translations/en.jsontranslations/<lang>.json
  3. Translate the values (keep keys as-is)
  4. Restart HA — cards and config UI load the new language automatically

Changes since beta.02

i18n — Config flow select options (new)

  • All SelectOptionDict labels replaced with translation_key + plain string values
  • 10 translation keys added to selector section: 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 to async_show_menu so 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 in setConfig)
  • 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 en to en-GB (matching actual source locale file)
  • Language fallback chain: en-GB → tries en-GB.json, pt-BR → tries pt-BR.jsonpt.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 (reads chore_completions) and sensor.taskmate_overview (reads todays_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_awarded for 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_dict methods
  • Points name/icon no longer overwritten on restart

Buttons & Sensors

  • Buttons update dynamically for new children/chores/rewards
  • Renamed ChoremandorOverallStatsSensorTaskMateOverallStatsSensor
  • 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_loop test 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.pytranslation_key selectors, list menus, _get_translation() helper
Frontend loader frontend.py — register localize module
Translation source strings.jsonselector 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.json2.3.0-beta.03

v2.3.0-beta3

31 Mar 12:17

Choose a tag to compare

v2.3.0-beta3 Pre-release
Pre-release

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.js module — detects hass.language, fetches matching locale, falls back to en-GB
  • Language fallback chain: nbnb.json, en-GBen-GB.json, pt-BRpt.jsonen-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 + selector section in strings.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:

  1. Copy www/locales/en-GB.jsonwww/locales/<lang>.json
  2. Copy translations/en.jsontranslations/<lang>.json
  3. Translate the values (keep keys as-is)
  4. Restart HA — cards and config UI load the new language automatically

Changes since beta.02

i18n — Config flow select options (new)

  • All SelectOptionDict labels replaced with translation_key + plain string values
  • 10 translation keys added to selector section: 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 to async_show_menu so 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 in setConfig)
  • 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 en to en-GB (matching actual source locale file)
  • Language fallback chain: en-GB → tries en-GB.json, pt-BR → tries pt-BR.jsonpt.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 (reads chore_completions) and sensor.taskmate_overview (reads todays_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_awarded for 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_dict methods
  • Points name/icon no longer overwritten on restart

Buttons & Sensors

  • Buttons update dynamically for new children/chores/rewards
  • Renamed ChoremandorOverallStatsSensorTaskMateOverallStatsSensor
  • 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_loop test 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.pytranslation_key selectors, list menus, _get_translation() helper
Frontend loader frontend.py — register localize module
Translation source strings.jsonselector 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.json2.3.0-beta.03

v2.3.0-b2

31 Mar 11:19
1a603be

Choose a tag to compare

v2.3.0-b2 Pre-release
Pre-release

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.js module loaded globally — detects language from hass.language, fetches the matching locale file, falls back to en-GB
  • 371 translation keys extracted from 14 JS cards into www/locales/ JSON files
  • Language fallback chain: en-GBen → key (handles regional variants like en-GB without 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:

  1. Copy www/locales/en-GB.jsonwww/locales/<lang>.json
  2. Copy translations/en.jsontranslations/<lang>.json
  3. Translate the values (keep keys as-is)
  4. 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 bonuscompletion.points_awarded stores 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 IDsasync_approve_chore and async_approve_reward now 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 from async_remove_reward. Previously, deleting a reward left orphaned claims causing errors.
  • Committed points TOCTOU fixed — the pending-claims loop in async_claim_reward now 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 fixedfrom_dict methods 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_done flag 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 ChoremandorOverallStatsSensor to TaskMateOverallStatsSensor (class name only — no entity ID change).
  • Sensor attributes cachedextra_state_attributes on the overview sensor is now cached per coordinator refresh, avoiding expensive recomputation on every HA poll.

Services

  • 6 missing service definitions addedpreview_sound, set_chore_order, add_penalty, update_penalty, remove_penalty, and apply_penalty now have proper entries in services.yaml and strings.json.

Code Quality

  • Penalty imports consolidated at module level in storage.py and coordinator.py.
  • Deprecated event_loop fixture removed from tests; added asyncio_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.json2.3.0-beta.02

2.3.0-beta.1

31 Mar 08:54
6f57f20

Choose a tag to compare

2.3.0-beta.1 Pre-release
Pre-release

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.js module 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:

  1. Copy www/locales/en.json to www/locales/<lang>.json (e.g. de.json for German)
  2. Translate the values (keep the keys as-is)
  3. 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 bonuscompletion.points_awarded stores 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 IDsasync_approve_chore and async_approve_reward now 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 from async_remove_reward. Previously, deleting a reward left orphaned claims causing errors.
  • Committed points TOCTOU fixed — the pending-claims loop in async_claim_reward now 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 fixedChild.from_dict, Chore.from_dict, Reward.from_dict, and Penalty.from_dict now 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_done flag 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 ChoremandorOverallStatsSensor to TaskMateOverallStatsSensor (class name only — no entity ID change).
  • Sensor attributes cachedextra_state_attributes on the overview sensor is now cached per coordinator refresh, avoiding expensive O(children × chores) recomputation on every HA poll.

Services

  • 6 missing service definitions addedpreview_sound, set_chore_order, add_penalty, update_penalty, remove_penalty, and apply_penalty now have proper entries in services.yaml and strings.json, so they appear correctly in Developer Tools.

Code Quality

  • Penalty imports consolidatedPenalty is now imported at module level in storage.py and coordinator.py instead of using late imports inside methods.
  • Deprecated event_loop fixture removed from test conftest; added asyncio_mode = auto to pytest.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

30 Mar 12:16
f26198e

Choose a tag to compare

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_completed recurrence records for that child
  • The child's ID from any chore assigned_to lists

Orphaned data cleanup on chore removal

Removing a chore now also cleans up:

  • All completions for that chore
  • All last_completed recurrence records for that chore
  • The chore's ID from any child's chore_order list

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_achieved and Child.awarded_perfect_weeks now use field(default_factory=list) instead of defaulting to None, eliminating the need for or [] guards throughout the codebase.
  • Penalty.assigned_to now uses list[str] with field(default_factory=list) instead of bare list = 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_completions API
  • Model tests updated to reflect proper list defaults (no longer testing None passthrough)

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_service to a non-notify domain (e.g., automation.trigger), it will now be ignored with a warning log. Update it to a valid notify.* service.

Full Changelog

Files changed:

  • custom_components/taskmate/models.py
  • custom_components/taskmate/coordinator.py
  • custom_components/taskmate/storage.py
  • custom_components/taskmate/__init__.py
  • custom_components/taskmate/config_flow.py
  • custom_components/taskmate/frontend.py
  • tests/test_coordinator_logic.py
  • tests/test_models.py

v2.1.0

24 Mar 19:06
af63e8f

Choose a tag to compare

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: a8c8376a

Bug Fixes

  • Crash deleting a chore — The config flow called a non-existent method (async_delete_chore) instead of the correct async_remove_chore. Deleting a chore from Settings now works correctly.

  • Crash when settings contain invalid values — If a setting like weekend_multiplier or perfect_week_bonus was 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 checkis_chore_available_for_child caught ValueError when parsing a stored date string, but not TypeError. If the stored value was None or a non-string, slicing it raised an unhandled TypeError. Fixed to catch both.

  • Reward rejection bypassed storage APIasync_reject_reward was directly writing to storage._data["reward_claims"] instead of going through the storage layer. Added remove_reward_claim() to TaskMateStorage and updated the coordinator to use it.

  • Double dict lookup for child names — A fragile a and b or c pattern 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

24 Mar 14:26
7c1d998

Choose a tag to compare

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

  1. Deploy all files to /config/custom_components/taskmate/
  2. Restart Home Assistant
  3. Review your rewards — check that costs are correct after the dynamic pricing removal
  4. Existing chores default to Specific Days scheduling — no action needed unless you want to convert any to Recurring

v2.0.0-beta-01

24 Mar 13:17
c13d0a9

Choose a tag to compare

v2.0.0-beta-01 Pre-release
Pre-release

Beta testing a new scoring system.