All notable changes to HA WashData will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Persistent Terminal States:
- Implemented proper
finished,interrupted, andforce_stoppedstates that persist for 30 minutes after cycle completion. - Improves visibility of cycle outcomes in the UI (users can now see "Finished" instead of just "Off").
- Auto-resets to
offafter 30 minutes, or immediately if a new cycle starts.
- Implemented proper
- Coffee Machine Defaults: Added dedicated defaults for coffee machines (faster sampling, shorter timeouts) to improve detection out-of-the-box.
- French Translation: Added full French localization (thanks to @MaximeNagel).
- Profile Sorting: Improved sorting for profile lists (natural sort), ensuring correct numeric order (e.g.
1, 2, 10instead of1, 10, 2). - Refactored Device Defaults: Consolidated and cleaned up device-specific default settings logic.
- Test Suite: Enhanced test coverage for cycle state transitions and manager notifications.
- Stuck Power Value: Fixed issue where the power entity would get stuck at the last non-zero value after a cycle ended.
- Timezone Display: Fixed issue where timestamps in specific UI menus were shown in GMT instead of local time.
- Advanced Settings Error: Fixed a crash that prevented advanced settings from being saved in the configuration flow.
- State Logic: Fixed assertions and logic validation for terminal states.
- Notification Tests: Fixed test environment formatting for notification services.
Major Architectural Rewrite ("vNext")
This release marks a complete re-engineering of the HA WashData core, transitioning from simple heuristics to a rigorous signal processing pipeline and robust state machine. While the version number is minor, this is effectively a new engine under the hood.
🎉 Milestones Reached!
- HA WashData is now available in the HACS Default Repository!
- Passed 1,000 active installations across the community.
- Reached 500+ stars on GitHub.
Thank you to everyone who has been patient during development and to all contributors who provided invaluable feedback, bug reports, and feature suggestions. This release wouldn't be possible without you!
Important
Fresh Start Recommended
This release includes significant changes to how cycles are detected and profiles are matched. The new engine depends on clean, accurate data to work properly.
If you're unsure whether your previously recorded cycles were captured correctly (e.g., cycles that ended prematurely, incorrectly merged fragments, or noisy data from before tuning your thresholds), we recommend:
- Delete your existing cycle history via Configure → Manage Cycles → Delete All
- Use the new "Record Cycle" feature to capture fresh, clean training data for each program you use
This ensures the best possible matching accuracy with the new architecture.
-
New Signal Processing Engine (
signal_processing.py):- Dt-Aware Integration: Replaced simple averaging with trapezoidal Riemann sum integration (
integrate_wh) that respects variable sampling intervals. - Robust Smoothing: Implemented
robust_smooth, a hybrid algorithm combining a Median Filter (spike rejection) with a Time-Aware Exponential Moving Average (EMA) for clean trend detection. - Adaptive Resampling: New primitives (
resample_adaptive,resample_uniform) handle irregular sensor updates and enforce strict gap handling (no interpolation across large gaps). - Idle Baseline Learning: Automatically learns the device's "true zero" using Median Absolute Deviation (MAD), removing the need for manual calibration.
- Dt-Aware Integration: Replaced simple averaging with trapezoidal Riemann sum integration (
-
Finite State Machine (FSM):
- Replaced binary ON/OFF logic with a formal FSM:
OFF→STARTING→RUNNING↔PAUSED→ENDING→OFF. - Dt-Aware Gating: Start/End detection now uses accumulated time/energy gates (e.g., "energy since idle > X Wh") rather than sample counts, making it immune to sensor update frequency.
- Smart Pausing: Distinguishes between "End of Cycle" and "Mid-Cycle Pause" using dynamic thresholds derived from the sensor's sampling cadence (
_p95_dt).
- Replaced binary ON/OFF logic with a formal FSM:
- Profile Store v2 (
profile_store.py):- New Schema: Introduced a versioned storage schema (v2) optimized for performance.
- Trace Compression: Historical power traces are now compressed using relative time deltas, significantly reducing disk usage.
- Robust Migration: Included a designated
WashDataStoreengine that automatically upgrades v1 data to v2 without data loss, preserving user labels and corrections.
- Configurable Sampling Interval: New "Sampling Interval" setting allows users to throttle high-frequency sensors (e.g., 1s updates) to reduce CPU load.
- Precision Configuration: Configuration flow now uses Text Box inputs for all numeric thresholds, offering precise control over parameters like
start_energy_threshold(Wh) anddrop_ratio. - Smart Resume: "Resurrection" logic restores the exact cycle state (including sub-state) after a Home Assistant restart.
- Auto-Labeling: Increased default confidence threshold to 0.75 (from 0.70) to leverage the improved accuracy of the new engine.
- Diagnostic Sensors: Added dynamic diagnostic sensors for each profile (e.g.,
sensor.washdata_..._profile_cotton_count) showing the total cycle count properly. - Statistics: Added "Total Energy" column to the Profile Statistics table, showing the cumulative energy consumed for each profile.
- Low-Rate Polling Support: Optimized default settings for devices with 30-60s update intervals (e.g., Shelly Cloud, Tuya), including a 30s watchdog and 180s off-delay.
- User Experience: moved "Review Learned Feedbacks" to the main menu (bottom) for easier access, and removed confusing options.
- Logging: Added more granular
termination_reasonlogging (e.g.,smart,timeout,force_stopped) tocycle_detectorandprofile_store. - Timezone Robustness: Complete refactor to use timezone-aware datetimes (
dt_util.now()) exclusively, permanently fixing "offset-naive/offset-aware" comparison errors. - Strict Typing: Codebase now strictly adheres to type hinting, with extensive use of
TypeAliasanddataclassfor internal structures. - Performance: Optimized
last_match_detailssensor attribute to exclude large raw data arrays, preventing Home Assistant state update bloat. - Serialization: Fixed
MatchResultJSON serialization issues that were blocking sensor updates.
- Premature Termination & Dishwasher Logic: Major robustness improvements for dishwashers.
- Implemented "Verified Pause" logic to prevent early termination during long drying phases.
- Added "End Spike Wait Period": Dishwashers now wait up to 5 extra minutes after expected duration to capture final pump-out spikes.
- Increased Smart Termination duration ratio to 0.99 (from 96%) to ensure strictly conservative termination for dishwashers.
- Ghost Cycles: Enhanced filtering and elimination of false detection.
- Persistent Suppression: The "Suspicious Window" (20 min) now persists across restarts (restoring
last_cycle_end), preventing end-spikes from triggering ghosts after reboots. - Tail Preservation: Disabled "zero trimming" for confirmed completed cycles, preventing the "profile shrinking" feedback loop where tails were lost.
- Implemented
completion_min_secondslogic to ignore brief spikes.
- Persistent Suppression: The "Suspicious Window" (20 min) now persists across restarts (restoring
- Start/End Flutter: Start debounce and End repeat counts are now configurable and backed by robust accumulators, eliminating false starts/ends.
- Cycle Detector: Adjusted duration validation logic to strict 90%-125% window for completion.
- Translations: Fixed "intl string context variable not provided" errors in logs by properly passing placeholders to translation engine.
- Debug Sensors: Fixed "Top Candidates" sensor showing "None" due to missing data propagation.
- Code Quality: Addressed various linting issues (indentation, whitespace, unused arguments).
- Crash Fixes: Resolved
UnboundLocalErrorand specific edge-case crashes inprofile_store.pyduring migration. - Critical Fix (Runtime Matching): Fixed an issue where runtime profile matching was blocking the event loop and skipping DTW; now uses the full async pipeline.
- Legacy Data Repair: Added automatic reconstruction of missing
time_gridin old profile envelopes to prevent errors. - Validation: Fixed missing
dtw_bandwidthkey instrings.jsoncausing config flow validation errors. - Maintenance Safety: Fixed aggressive cleanup logic that was deleting empty/new profiles (pending training); these are now safely preserved.
- Test Suite: Fixed verification tests for Smart Termination and Profile Store matching.
- Visual Settings Guide: Expanded
SETTINGS_VISUALIZED.mdwith comprehensive documentation for 20+ parameters, organized into logical sections (Signal Conditioning, Detection, Matching, Integrity, Interruption, Learning, Notifications). - Complete Parameter Coverage: All advanced settings now documented with explanations, including
sampling_interval,watchdog_interval,profile_match_threshold,duration_tolerance,learning_confidence,auto_label_confidence, andabrupt_drop_ratio.
- Removed
auto_merge_gap_seconds: This setting was never used in the actual merge logic; removed from code, config flow, and translations. - Removed
auto_merge_lookback_hours: Similar unused legacy setting removed from codebase and UI. - Fixed Unused Imports: Cleaned up unused
DEFAULT_PROFILE_MATCH_MAX_DURATION_RATIOand duplicate import warnings. - Fixed F-String Warning: Removed empty f-string in config_flow post-process step.
- Legacy Logic: Removed "consecutive samples" based detection in favor of time-aware accumulators.
- Sliders: Removed slider inputs in config flow in favor of precise text inputs.
- Manual Control: "Force End Cycle" button to manually terminate stuck cycles (treats as "Completed" and saves data).
- Reliability: "Cycle Resurrection" logic to restore active cycle state after Home Assistant restarts.
- Reliability: "Smart Resume" estimation to provide progress updates during "detecting..." phase based on historical averages.
- Smart Cycle Extension: New feature to prevent premature cycle termination during long low-power phases (e.g., dishwasher drying).
- Statistics: Energy (kWh) estimates added to Profile Statistics table.
- UI: Added legends to profile graphs and scaled them up by 50% for better readability.
- Config Flow: Split "Manage Data" into "Manage Cycles" and "Manage Profiles" menus for better usability.
- Config Flow: Added ability to manually edit profile "Average Duration" for tuning Smart Extension.
- Icons: Fixed missing icon for "Cycle Program" select entity (now dynamically adapts to device type).
- Frontend: Added missing "min" unit to "Time Remaining" display on card.
- Logic: Improved filtering of "Ghost Cycles" (extremely short noise events).
- Bug: Fixed JSON serialization error preventing status updates in some cases.
- Bug: Ensure stats are immediately rebuilt after merging cycles.
- Translation Keys: Corrected missing labels for "Smart Extension Threshold" and other advanced settings.
- Manual Duration for Profiles: Users can now specify a manual "Baseline Duration" when creating profiles, useful for setting up profiles without historical data (e.g., "Eco Mode - 180 mins").
- Onboarding First Profile Step: New users are now prompted to optionally create their first profile immediately after setting up the device, streamlining the initial experience.
- Automatic Recalculation: Deleting a cycle now automatically triggers a recalculation of the associated profile's statistical envelope, ensuring accurate estimates even after cleaning up bad data.
- Translations: Fixed missing text labels in the "Create Profile" modal and Onboarding flow.
- Configuration Flow: Resolved
AttributeError: _get_schemain the initial setup step. - Mocking Issues: Improved test verification process for Config Flow.
- Manual Override: Fixed issue where unselecting a manual profile while idle would not clear the program sensor.
This release marks a significant milestone for HA WashData, introducing intelligent profile-based cycle detection, a dedicated dashboard card, a completely rewritten configuration experience, and major improvements to cycle detection and time estimation.
Brand new in v0.3.0! A native-feeling Lovelace card designed specifically for washing machines, dryers, and dishwashers.
- Compact Tile Design: A sleek 1x6 row layout that fits perfectly with standard Home Assistant tile cards
- Dynamic Styling: Configure a custom Active Icon Color (e.g., Green or Blue) that lights up only when the appliance is running
- Program Display: Directly shows the detected or selected program (e.g., "Cotton 60°C") via the new Program Entity selector
- Smart Details: Toggle between "Time Remaining" (estimated) and "Progress %" as the primary status indicator
- Shadow DOM Implementation: Isolated styling to prevent conflicts with other Home Assistant components
New cycle detection capabilities powered by NumPy:
- Profile-Based Detection: Learns appliance cycle patterns and uses shape correlation matching (MAE, correlation, peak similarity) to identify cycles in real-time
- Predictive Cycle Ending: Short-circuits the
off_delaywait when a cycle matches with high confidence (>90%) and is >98% complete, reducing unnecessary wait times by up to 30 seconds - Confidence Boosting: Adds a 20% score boost to profile matches with exceptionally high shape correlation (>0.85)
- Smart Time Prediction: Detects high-variance phases (e.g., heating) and "locks" the time estimate to prevent erratic jumps during unstable phases
- Cycle Extension Logic: Automatically extends cycles when profile matching indicates the appliance is still running, preventing premature cycle end detection
- Sub-State Reporting: Displays detailed cycle phases (e.g., "Running (Heating)", "Running (Cotton 60°C - 75%)") for better visibility
- Profile Persistence: Detected cycle profile names are now persisted and restored across Home Assistant restarts
- New
select.<name>_program_selectentity for manual program overrides and system teaching - Allows users to manually select the active program, helping the system learn and improve detection accuracy
The configuration flow has been rebuilt from the ground up to be friendlier and more organized:
- Two-Step Wizard:
- Step 1 (Basic): Essential settings (Device Type, Power Sensor) and Notifications are now properly grouped here
- Step 2 (Advanced): Accessible via the "Edit Advanced Settings" checkbox, containing fine-tuning options for power thresholds and timeouts
- Smart Suggestions: The "Apply Suggested Values" feature is now integrated into the Advanced step, helping you easily adopt values learned by the engine
- Reactive Synchronization: All profile/cycle modifications (create/delete/rename/label) trigger updates to keep the
selectentity in sync - Precision UI: Replaced sliders with precise text-based box inputs for all configuration parameters
- Start Duration Threshold: Now configurable in advanced settings (previously hard-coded)
New logic to handle tricky appliances and prevent false detections:
- Start Debounce Filtering: Configurable debounce period to ignore brief power spikes before confirming cycle start
- Running Dead Zone: A new setting to ignore power dips during the first few seconds of a cycle (useful for machines that pause shortly after starting)
- End Repeat Count: Requires the "Off" condition to be met multiple times consecutively before finishing a cycle, preventing false cycle ends during long pauses/soaking
- Ghost Cycle Prevention: Added
completion_min_secondsto filter out short "noise" cycles from being recorded as completed - Device Type Configuration: Support for multiple appliance types (washing machine, dryer, dishwasher, coffee machine) with device-type-aware progress smoothing thresholds
- EMA Smoothing: Implemented Exponential Moving Average smoothing for progress and time-remaining sensors, eliminating the "jumping" behavior seen in previous versions
- Monotonic Progress: The progress percentage is now (almost) strictly enforced to never go backwards, ensuring a consistent countdown experience
- Smoothed Progress Initialization:
_smoothed_progressis now properly initialized in__init__to avoid runtime errors - Smart Phase Detection: High-variance phases are detected and handled separately to prevent estimate instability
- Configurable alerts (
notify_before_end_minutes) before estimated cycle end - Helps users prepare for cycle completion without constant monitoring
- Data-Driven Tests: New test suite
tests/test_real_data.pyreplays real-world CSV/JSON cycle data - Manager Tests: New
tests/test_manager.pyfor comprehensive manager functionality testing - Profile Store Tests: New
tests/test_profile_store.pyfor storage and matching validation - Restart Persistence Tests: New
tests/repro/test_restart_persistence.pyto verify state recovery - Cycle Detector Improvements: Enhanced
tests/test_cycle_detector.pywith new test cases - Conftest Utilities: Added
tests/conftest.pywith shared test fixtures
- GitHub Actions Workflows: Added
hassfest.ymlandvalidate.ymlfor automated validation - Enhanced Mock Tooling:
devtools/mqtt_mock_socket.pynow supports:--speedup X: Compresses time for faster testing--variability Y: Adds realistic duration variance (default 0.15) for shape matching validation--fault [DROPOUT|GLITCH|STUCK|INCOMPLETE]: Injects anomalies for resilience testing
- Secrets Template: Added
devtools/secrets.py.templatefor easier development setup
- Enhanced README: Completely rewritten with detailed configuration options, examples, and troubleshooting
- Updated IMPLEMENTATION.md: Reflects new architecture with NumPy-powered matching and profile persistence
- Improved TESTING.md: Enhanced verification guide with new test scenarios
- Screenshot Assets: Added screenshots in
img/directory:integration-controls.pngintegration-diagnostics.pngintegration-profiles.pngintegration-sensors.pngintegration-settings.png
- GitHub Funding: Added
.github/FUNDING.ymlfor sponsor support
- Manifest Dependencies: Added
lovelaceandhttptoafter_dependenciesto ensure reliable card loading - NumPy Requirement: Added
numpyto requirements for advanced shape correlation matching - Service Definitions: Enhanced
services.yamlwith new export and configuration options - Profile Store Refactoring: Complete rewrite for improved type safety, compression, and NumPy-powered matching
- Manager Enhancements:
- Better state machine handling with reactive synchronization
- Improved notification system
- Enhanced progress tracking with device-type-aware smoothing
- Power sensor change protection (blocked when cycle is active)
- Cycle Detector Evolution:
- More robust state transitions
- Better handling of edge cases
- Enhanced logging for debugging
- Translation Updates: Full translation support for new wizard steps and advanced settings in both
strings.jsonandtranslations/en.json - Configuration Validation: Improved validation and error handling in config flow
- Settings Migration: Automatic migration of existing settings to new format
- Fixed Indentation Issues: Corrected inconsistent indentation throughout codebase
- Removed Trailing Whitespace: Cleaned up formatting issues
- Removed Unused Variables: Eliminated unused
managervariable fromasync_step_settings - Removed Unused Imports: Cleaned up
MagicMockandSTATE_OFFimports from test files - Improved Error Handling: Added descriptive debug logging for exception handling
- Fixed Redundant Code: Removed duplicate
device_typeassignment in cycle data - Memory Leak Prevention: Fixed event listener accumulation in dashboard card
- Performance Optimization: Implemented result caching for profile matcher to avoid redundant calls
- Deprecated Auto-Maintenance Switch: Removed standalone
auto_maintenanceswitch entity (now a backend setting)
- README Path Inconsistency: Corrected card path documentation from
/ha_washdata/card.jsto/ha_washdata/ha-washdata-card.js - Card Editor Domain Support: Added "select" entity domain to program_entity selector in dashboard card editor
- End Condition Counter: Fixed potential infinite increment issue when power stays low for extended periods
- Start Duration Threshold: Removed unconditional override in initial setup to allow user customization
- Cycle Interruption Handling: Better detection and classification of interrupted, force-stopped, and resumed cycles
- Profile Match Extension: Added confidence check (≥70%) to prevent spurious cycle extensions
- Config Flow Import: Removed duplicate import of
CONF_AUTO_MERGE_GAP_SECONDS - Power Sensor Change: Now properly blocked when a cycle is active to prevent data inconsistency
- All code changes have been validated through CodeQL security scanning
- No new vulnerabilities introduced
- Automatic Migration: Your existing settings will be migrated automatically to the new format
- Card Setup: After updating, look for the "WashData Card" in the dashboard card picker
- Select Entity: A new
select.<name>_program_selectentity will be created automatically - Deprecated Switch: The
auto_maintenanceswitch entity will be removed; this is now a backend setting
None. This release is fully backward compatible with v0.2.x configurations.
See git history for details on previous releases.