-
-
Notifications
You must be signed in to change notification settings - Fork 41
Testing
Updated: July 2026
The primary automated suite is the pytest fast / slow / benchmark split below (
./run_tests.sh), which also runs a headless panel render smoke test (devtools/panel_smoke.js) before pytest. The MQTT mock-socket walkthroughs further down are for manual end-to-end verification against a running Home Assistant.
Note: Despite the name, WashData also works well for other appliances (e.g., dryers and dishwashers) as long as the power-draw cycle is reasonably predictable.
- Quick Start
- Test Categories (fast / slow / benchmark)
- Test 1: Cycle Duration Variance
- Test 2: Progress Management
- Test 3: Learning Feedback System
- Test 4: Cycle Status Classification
- Test 5: Publish-on-Change Sockets
- Test 6: Profile Switching Verification
- Test 7: Data-Driven Verification (Real Data)
- Test 8: Comprehensive Logic Verification
- Test 9: Empty Profile Safety (Edge Case)
- Mock Socket Reference
- Debugging
# Install Home Assistant (if not already)
# ha_washdata integration installed in Home Assistant
# MQTT broker configured
# Optional: paho-mqtt for mock socket
pip install paho-mqtt# Fast suite (default) – ~30s, skips real-data replays and benchmarks
./run_tests.sh
# Playwright E2E browser tests (panel UI; ~30s, 332 tests across chromium + mobile-chrome)
./run_tests.sh --e2e
# Everything (fast + slow + benchmark + E2E, ~12 min)
./run_tests.sh --all
# Run a single test file
./.venv/bin/pytest tests/test_cycle_detector.py -v
# Syntax check
python3 -m compileall custom_components/ha_washdata tests/ --quiet
# Start mock socket simulator (manual end-to-end)
python3 devtools/mqtt_mock_socket.py --speedup 720 --default LONGSee Test Categories for the full suite and how to opt in to slow / benchmark / E2E runs.
Tests are split into four categories so the dev loop stays fast. The Python
tests use pytest markers; the browser tests are a separate Playwright suite. The
default ./run_tests.sh (and raw pytest tests/) runs only the fast subset
– about 30 seconds for UI / config / unit changes. The other categories are
opt-in for releases and CI (--slow, --bench, --e2e, or --all).
| Category | Marker / runner | What it covers | Default? |
|---|---|---|---|
| fast | (none) | Unit & integration tests with mocked dependencies, issue reproducers | ✅ runs |
| slow | @pytest.mark.slow |
Real-data replays from cycle_data/, stress simulations, full HA flow |
❌ --slow
|
| benchmark | @pytest.mark.benchmark |
Performance characterization (timing prints, no functional assertions) | ❌ --bench
|
| e2e | Playwright (playwright-tests/) |
Full panel UI across chromium + mobile-chrome (332 tests). Required for any panel change. | ❌ --e2e
|
Run the browser suite with ./run_tests.sh --e2e, or directly:
cd playwright-tests && npx playwright test (single spec:
npx playwright test tests/settings.spec.ts; interactive: npx playwright test --ui).
The test server (serve.mjs) and the WS mock start automatically. When you add
or change a panel feature, add or update the matching spec in playwright-tests/tests/.
./run_tests.sh # Fast suite only (default, ~30s)
./run_tests.sh --slow # Only slow tests (real-data replays, stress sims)
./run_tests.sh --bench # Only benchmarks
./run_tests.sh --all # Everything (~12 min)
# Pass extra pytest args after the mode keyword:
./run_tests.sh --slow -v -k verify_alignment
./run_tests.sh -k cycle_detector # fast subset, filteredThe default-skip filter lives in pytest.ini (addopts = -m "not slow and not benchmark").
Raw pytest tests/ honors it too; pass -m "" to override.
A test should be marked slow if it:
- loads files from
cycle_data/(replays real appliance traces, ~hundreds of MB) - runs a parametrized fan-out over many cycles
- boots the full Home Assistant fixture and synthesizes a complete cycle
- takes more than ~1.5 seconds in isolation
Add the marker at module level for whole files:
import pytest
pytestmark = pytest.mark.slow…or per test for mixed files (see tests/test_analysis_bench.py):
@pytest.mark.benchmark
def test_dtw_lite_performance():
...slow: tests/repro/test_comprehensive_stress_suite.py,
tests/repro/test_stress_smart_termination.py,
tests/repro/test_smart_termination.py,
tests/test_verify_alignment.py, tests/test_real_data.py,
tests/test_real_data_suggestions.py, tests/test_trailing_zero_impact.py,
tests/test_integration_flow.py, tests/test_reprocessing.py,
tests/test_phase_segmenter.py, tests/test_playground_detail.py,
tests/test_issue_offdelay_smart_debounce.py, tests/test_matching_tuner.py,
tests/test_issue_296_anticrease_back_to_back.py
benchmark: tests/test_benchmark_matching.py,
tests/test_analysis_bench.py::test_dtw_lite_performance
Verify that the system correctly handles realistic cycle time variance.
- Start mock socket with specific variability:
cd /root/ha_washdata
# Force 5% variability for testing
python3 devtools/mqtt_mock_socket.py --speedup 720 --default LONG --variability 0.05- Expected output:
[INFO] Starting MQTT mock socket
[INFO] Publishing to topic: home/laundry/power
[VARIANCE] Applied +8.3% duration variance (factor: 1.083x)
[INFO] Simulating LONG cycle (~2:39)
[INFO] Phase 1/3: heating for 161 seconds...
...
[INFO] Cycle complete, cycle duration: 164s
-
Watch console for variance messages:
- Should see
[VARIANCE]logged each cycle - Percentage should be between -15% and +15%
- Should see
-
Check cycle durations in Home Assistant logs:
grep -i "cycle_duration\|variance" /path/to/ha/logs/home-assistant.log- Create profiles and verify matching:
# Via Home Assistant Developer Tools
# 1. Run a 60°C Cotton cycle (base duration ~60 min)
# 2. Check detected duration in sensor.time_remaining
# 3. Run another cycle with variance (~52-68 min depending on variance)
# 4. Verify it still matches the "60°C Cotton" profile
# Log should show:
# [DEBUG] Matched profile '60°C Cotton' with expected duration 3600s
# [DEBUG] Duration ratio: 0.95 (±5%) - ACCEPTED (tolerance: ±25%)| Scenario | Expected Behavior |
|---|---|
| Same program, +10% variance | Matches profile (confidence ~0.7+) |
| Same program, -10% variance | Matches profile (confidence ~0.7+) |
| Different program | Rejected or low confidence |
| Variance > ±25% | Rejected (duration out of tolerance) |
Problem: No variance messages in console
# Check mock socket is publishing:
mosquitto_sub -h localhost -t "home/laundry/power"
# Should see power values changing
# Verify variance code is enabled:
grep -n "variance_factor" devtools/mqtt_mock_socket.pyProblem: Cycles not matching despite variance
# Variance is handled in several places:
# 1. Mock socket: --variability (default 0.15)
# 2. Profile matching: ±25% duration tolerance
# 3. Shape Matching: NumPy correlation score (must be > learning_confidence)
# Check the duration-ratio gate + tolerance (see const.py MATCH_* / profile_duration_tolerance):
grep -n "MATCH_\|DURATION_RATIO" custom_components/ha_washdata/const.pyVerify progress correctly shows 100% at completion and resets to 0% after idle.
- Start a cycle:
service: mqtt.publish
data:
topic: home/laundry/power
payload: "100" # High power = cycle runningOr use mock socket:
python3 devtools/mqtt_mock_socket.py --speedup 720 --default SHORT- Monitor progress entity:
# In Home Assistant Developer Tools → States
sensor.washer_progress: "0" # Initial
sensor.washer_progress: "25" # Mid-cycle
sensor.washer_progress: "50" # Mid-cycle
sensor.washer_progress: "75" # Near completion
sensor.washer_progress: "100" # CYCLE COMPLETE- Check logs:
grep "Updated estimates: progress" home-assistant.log
# Should see: progress increasing from 0-100%-
Let cycle complete (progress → 100%)
-
Note the time when progress reaches 100%
-
Wait for the Progress Reset Delay (default 30 min) with no new cycle
-
Check progress entity:
# Immediately after cycle complete
sensor.washer_progress: "100"
# After the reset delay (default 30 min / 1800s) idle
sensor.washer_progress: "0"- Check logs for reset confirmation:
grep "Progress reset\|Starting progress reset" home-assistant.log
# Expected output:
# [DEBUG] Starting progress reset timer (will reset after 1800s (the configurable Progress Reset Delay; default 30 min))
# [DEBUG] Progress reset: cycle idle for 1800.0s (threshold: 1800s)-
Run cycle to completion (progress → 100%)
-
Wait a short time (before the reset delay elapses)
-
Start a new cycle within the reset window
-
Verify progress resets to 0% immediately:
# Before new cycle
sensor.washer_progress: "100"
# Immediately after new cycle starts
sensor.washer_progress: "0"
# New cycle progress begins (0-100%)
sensor.washer_progress: "15"
sensor.washer_progress: "30"- Check logs for reset cancellation:
grep "Washer state changed.*running\|Stopping progress reset" home-assistant.log
# Expected:
# [DEBUG] Stopping progress reset timer (new cycle started)State Transitions:
─────────────────
Initial State:
sensor.washer_progress: "0"
During Cycle:
sensor.washer_progress: 0 → 100 (as cycle runs)
Cycle Complete:
sensor.washer_progress: 100 (held for the reset delay, default 30 min)
After Idle (no new cycle):
sensor.washer_progress: 0 (auto-reset)
Or: New Cycle (within the reset window):
sensor.washer_progress: 0 (immediate reset)
→ Cycle resumes from 0
Verify feedback requests are emitted and accepted correctly; learning updates profiles.
- Create a test profile:
# Via Home Assistant Services:
# First, run a cycle and let it complete
# Then create a profile:
service: ha_washdata.label_cycle
data:
device_id: washer_device_id
cycle_id: recent_cycle_id
profile_name: "Test Profile 60C"- Run another cycle to create data:
python3 devtools/mqtt_mock_socket.py --speedup 720 --default LONG- Monitor Home Assistant events:
# Developer Tools → Events
# Listen for: ha_washdata_feedback_requested
# You should receive event with:
{
"event_type": "ha_washdata_feedback_requested",
"data": {
"cycle_id": "abc123xyz",
"detected_profile": "Test Profile 60C",
"confidence": 0.75,
"estimated_duration": 60,
"actual_duration": 62,
"is_close_match": true,
"created_at": "2025-12-17T15:30:00+00:00"
}
}- Check logs for feedback request:
grep "Feedback requested\|request_cycle_verification" home-assistant.log
# Expected:
# [INFO] Feedback requested for cycle abc123: profile='60°C Cotton'
# (conf=0.75), est=60min, actual=62min (103.3%) - is_close=True-
Get cycle_id from previous test (or logs)
-
Call submit feedback service:
service: ha_washdata.submit_cycle_feedback
data:
entry_id: "integration_entry_id"
cycle_id: "abc123xyz"
user_confirmed: true
notes: "Detected correctly!"- Verify service response:
# Service call should succeed (no errors)
# Check Home Assistant notifications for confirmation- Check logs:
grep "Cycle feedback submitted\|user_confirmed.*true" home-assistant.log
# Expected:
# [INFO] Cycle feedback submitted for cycle_id abc123xyz
# user_confirmed=True, original_profile='60°C Cotton'- Verify cycle marked:
# In diagnostics/storage:
# Cycle should have flag: feedback_corrected: true-
Get cycle_id (from feedback event or logs)
-
Call service with correction:
service: ha_washdata.submit_cycle_feedback
data:
entry_id: "integration_entry_id"
cycle_id: "abc123xyz"
user_confirmed: false
corrected_profile: "40°C Delicate"
corrected_duration: 3300 # seconds (55 minutes)
notes: "Wrong program - actually a delicate cycle"- Verify correction:
grep "Applying correction learning\|avg_duration" home-assistant.log
# Expected:
# [INFO] Applying correction learning for profile '40°C Delicate'
# Old duration: 2700s, Correction: 3300s
# Profile stats recomputed from labelled cycles (no EWMA): re-labels the cycle, then rebuilds the envelope and avg/min/max from the profile's cycles- Verify profile was updated:
# Future cycles use the recomputed avg_duration (robust median over labelled cycles)
# Matching then uses the recomputed avg ± tolerance (default ±25%)- After several feedback submissions:
# Check learning statistics programmatically:
# Via HA integration (if exposed):
sensor.washdata_learning_stats:
total_feedback: 5
confirmations: 3
corrections: 2
pending: 0- Get pending feedback:
# Via Developer Tools / Python script:
# manager.learning_manager.get_pending_feedback()
# Should return cycles awaiting user input- Get feedback history:
# Via Developer Tools / Python script:
# manager.learning_manager.get_feedback_history(limit=10)
# Should return recent feedback records-
Create profile from cycle with unknown duration
-
Submit corrected feedback (different duration)
-
Run another cycle with original detected program
-
Verify:
- Profile avg_duration updated
- Time remaining shows corrected duration
- Confidence remains high (learned profile)
Verify that natural finishes show ✓ (completed or force_stopped) and abnormal endings show ✗ (interrupted).
- Normal completion (✓ completed):
- Run a normal cycle with the mock socket (e.g., LONG) and let it finish.
- Verify status in logs/diagnostics shows
status: completed.
- Watchdog finish while low-power waiting (✓ force_stopped):
- Stop mock publishing right after entering low-power wait phase.
- Ensure no updates for ≥
off_delay; the manager will callforce_end(). - Verify status shows
status: force_stopped(treated as ✓ in UI).
- Interrupted (✗ interrupted):
- Start a cycle, then abruptly cut power to 0W early (e.g., after ~60s).
- Or use a fault profile (e.g.,
LONG_INCOMPLETE) and stop updates before low-power wait. - Verify status shows
status: interrupted.
grep -i "status:\|force_end\|interrupted" /config/home-assistant.logExpected lines:
-
status: completedorstatus: force_stoppedfor ✓ cases -
status: interruptedfor abnormal endings
Validate watchdog behavior with devices that publish every ~60s and pause when values are steady.
- Configure
no_update_active_timeout(e.g., 600s) in Options. - Run a cycle and simulate 60s publishing intervals (
--sample 60). - During an active phase, pause updates for <
no_update_active_timeout(e.g., 5 minutes when timeout is 10 minutes). - Confirm the cycle is NOT force-ended while power is still high.
- Enter low-power wait and pause updates for ≥
off_delay; confirm the cycle is completed (✓) even without new publishes.
grep -i "watchdog\|no_update_active_timeout\|low-power wait" /config/home-assistant.logExpected behavior:
- Active but no updates < timeout → no force-end.
- Low-power wait ≥ off_delay without updates → natural completion (✓).
Verify the system correctly switches profiles when a better match is found mid-cycle (e.g. initial match was weak, then strong match appears).
- Start Cycle: Begin a cycle that looks like Profile A initially.
-
Verify A: Check
sensor.<name>_programis "Profile A". - Change Pattern: Emit data that strongly matches Profile B (e.g., specific spin pattern).
-
Verify Switch:
- Check logs for "Switching to profile 'Profile B' (reason: high_confidence_override)".
- Verify
sensor.<name>_programchanges to "Profile B".
Verify the integration robustness against real-world data anomalies (sampling gaps, noise) using recorded traces from actual appliances.
The repository includes a dedicated test suite tests/test_real_data.py that replays CSV/JSON data files through the CycleDetector state machine.
# Run the data-driven test suite
pytest tests/test_real_data.py -v-
cycle_data/dishwasher-power.csv(Dishwasher drying phase logic) -
cycle_data/real-washing-machine.json(Real washing machine trace) -
cycle_data/test-mock-socket.json(High-frequency mock data)
- Phase Detection: Correctly identifies "Drying" phases even with 0W power gaps.
- Cycle Consistency: Ensures varying sampling rates don't cause fragmented cycles.
- High-Frequency Stability: Verifies 2s sampling rate doesn't overwhelm the detector.
To add your own data, export a cycle JSON and add a new test case in tests/test_real_data.py.
Verify the internal logic of the WashDataManager regarding profile switching, unmatching, and time prediction without needing a full-blown simulation. This runs a granular suite of scenario-based unit tests.
pytest tests/test_logic_comprehensive.py -v- Initial Match: "detecting..." -> Matched Profile.
- Strong Override: Switching to a significantly better match mid-cycle.
- Weak Improvement: Ignoring marginal confidence gains to prevent thrashing.
- Unmatching: Reverting to "detecting..." when confidence collapses (drastic change).
- Variance Locking: FREEZING the time estimate during high-variance phases (e.g., heating).
- Normal Prediction: Updating estimates smoothly during low-variance phases.
Verify that the maintenance cleanup logic does NOT delete "Empty Profiles" (created by the user but not yet trained with a cycle), which was a previously fixed bug.
pytest tests/test_empty_profile_deletion.py -v- Passed: The test confirms empty profiles are preserved while broken references are deleted.
cd /root/ha_washdata/devtools
pip install paho-mqtt # If not already installed
# Default: 720x speedup (2h → 10s)
python3 mqtt_mock_socket.py
# Custom speedup
python3 mqtt_mock_socket.py --speedup 360 # 2x speed
python3 mqtt_mock_socket.py --speedup 1440 # 4x speed
# Custom cycle type
python3 mqtt_mock_socket.py --default SHORT # 45 min base
python3 mqtt_mock_socket.py --default MEDIUM # 90 min base
python3 mqtt_mock_socket.py --default LONG # 159 min basepython3 mqtt_mock_socket.py \
--host localhost # MQTT broker (default: localhost)
--port 1883 # MQTT port (default: 1883)
--speedup 720 # Time compression (default: 720)
--sample 60 # Sampling period in seconds (default: 60)
--jitter 15 # Power noise ±W (default: 15)
--variability 0.15 # Cycle duration variance percentage (default: 0.15)
--default LONG # Default cycle (default: LONG)| Type | Base Duration | Phases |
|---|---|---|
| SHORT | 45 min | Heat (5m), Wash (15m), Spin (5m) |
| MEDIUM | 90 min | Heat (10m), Wash (40m), Rinse (20m), Spin (20m) |
| LONG | 159 min | Heat (20m), Wash (60m), Rinse (40m), Spin (39m) |
Append suffixes to cycle types to simulate real-world failures:
| Mode | Example | Scenario | Tests |
|---|---|---|---|
| Normal | LONG |
Clean completion | Baseline detection |
_DROPOUT |
LONG_DROPOUT |
Sensor offline | Watchdog timeout |
_GLITCH |
MEDIUM_GLITCH |
Power noise/spikes | Smoothing filter |
_STUCK |
SHORT_STUCK |
Phase loops | Forced cycle end |
_INCOMPLETE |
LONG_INCOMPLETE |
Never finishes | Stale detection |
Note: The examples above use both a generic topic (e.g., home/laundry/power) and the mock's command topic (homeassistant/mock_washer_power/cmd). Adjust topics to match your environment.
Usage:
# Normal cycles
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'LONG'
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'MEDIUM'
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'SHORT'
# With fault injection
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'LONG_DROPOUT' # Sensor offline
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'MEDIUM_GLITCH' # Power noise
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'SHORT_STUCK' # Stuck phase
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'LONG_INCOMPLETE' # Never ends
# Stop
mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'OFF'- Scenario: Sensor loses connection mid-cycle (~60% through)
- Expected: Watchdog detects no updates for ~120s, forces cycle end
- Tests: Connection recovery, stale cycle detection
- Scenario: 15% chance of brief 0W dips or power spikes per reading
- Expected: 5-sample moving average smooths noise, cycle continues
- Tests: Smoothing filter, no false cycle end
- Scenario: One phase repeats indefinitely (~5 loops)
- Expected: 4-hour safety timeout or watchdog forces end
- Tests: Stuck detection, forced cycle completion
- Scenario: Cycle stops publishing (frozen at last value)
- Expected: Watchdog detects stalled sensor, forces cycle end
- Tests: Stale detection, watchdog intervention
Default:
- Host: localhost
- Port: 1883
- Topic: homeassistant/mock_washer_power/power
- Payload: Power in watts (0-500)
Override via environment:
export MQTT_HOST=192.168.1.100
export MQTT_PORT=1883
python3 mqtt_mock_socket.py======================================================================
MQTT Mock Washer Socket - Ready for Testing
======================================================================
Connected to MQTT: localhost:1883
Speedup: 720x, Jitter: ±15W, Sample: 60s
[INFO] Starting cycle: LONG (~2:39)
[VARIANCE] Applied +8.3% duration variance (factor: 1.083x)
[INFO] Phase 1/3: heating for 22 seconds... Power: 150W
[INFO] Phase 2/3: washing for 67 seconds... Power: 250W
[INFO] Phase 3/3: spinning for 44 seconds... Power: 350W
[INFO] Cycle complete, duration: 168s
✅ Realistic simulation - ±15% duration variance
✅ Multiple cycle types - SHORT, MEDIUM, LONG
✅ Fault injection - DROPOUT, GLITCH, STUCK, INCOMPLETE
✅ Configurable parameters - speedup, jitter, sampling
✅ Detailed logging - All events visible in console
✅ MQTT autodiscovery - Entities auto-appear in HA
-
Cycle Detection
- ✅ Binary sensor
runningmatches active cycle - ✅ Cycle ends at expected time (not premature, not hanging)
- ✅ Power profile saved in compressed format
- ✅ Binary sensor
-
Fault Handling
- ✅ DROPOUT: Ends when sensor offline (watchdog)
- ✅ GLITCH: Completes despite noise (moving average)
- ✅ STUCK: Eventually ends (timeout or watchdog)
- ✅ INCOMPLETE: Detected as stalled (watchdog)
-
Integration State
- ✅
washer_programshows detected program - ✅
time_remainingupdates while running - ✅
cycle_progressshows 0-100% - ✅ No "unknown" state thrashing
- ✅
In Home Assistant configuration.yaml:
logger:
default: info
logs:
custom_components.ha_washdata: debugThen restart Home Assistant:
service: homeassistant.restart# Watch live logs
tail -f /config/home-assistant.log | grep ha_washdata
# Search for specific events
grep "Matched profile\|Feedback requested\|Progress reset" /config/home-assistant.log
# Count occurrences
grep -c "Cycle complete" /config/home-assistant.logIssue: Progress not updating
# Check if power readings are coming in
grep "Power.*changed\|_async_power_changed" home-assistant.log
# Check cycle detector state
grep "STATE_RUNNING\|STATE_OFF" home-assistant.log
# Verify min_power setting
grep "min_power\|Configuration" home-assistant.logIssue: Feedback event not emitted
# Check confidence threshold
grep "confidence\|Feedback requested\|High" home-assistant.log
# Verify match was found
grep "Matched profile" home-assistant.log
# Check event system
service: ha_washdata.label_cycle # Manually triggerIssue: Learning not applied
# Verify feedback was received
grep "Cycle feedback submitted" home-assistant.log
# Check correction learning
grep "Applying correction learning" home-assistant.log
# Verify storage was updated
grep "async_save\|Store updated" home-assistant.log# Check cycle detection performance
grep "process_reading\|state change" home-assistant.log | wc -l
# Should be ~1 per 2.5 seconds
# Check profile matching load
grep "_update_estimates" home-assistant.log | wc -l
# Should be ~1 every 5 minutes per cycle
# Check event emission rate
grep "ha_washdata_cycle_started\|ha_washdata_cycle_ended" home-assistant.log | wc -l
# Should be 1 per cycle# Run fast suite (default, ~30s)
cd /root/ha_washdata
./run_tests.sh
# Run everything (fast + slow + benchmark, ~12 min)
./run_tests.sh --all
# Run specific test
./.venv/bin/pytest tests/test_cycle_detector.py::TestCycleDetector::test_state_machine -v
# Run with coverage (fast suite)
./.venv/bin/pytest tests/ --cov=custom_components/ha_washdataSee Test Categories for the fast/slow/benchmark split.
- Syntax:
python3 -m py_compile custom_components/ha_washdata/*.py - Mock socket:
python3 devtools/mqtt_mock_socket.py --speedup 720 - Progress reaches 100% on cycle completion
- Progress resets to 0% after the reset delay (default 30 min) idle
- Quick restart cancels reset timer
- Feedback request event emitted
- Submit feedback service works
- Learning updates profiles
- Integration loads without errors
- Entities appear in Home Assistant
- Power sensor readings updating
- Cycles detected correctly
- Progress tracking works
- Events visible in event log
- Learning system responding
- Run multiple cycles of different programs
- Verify profiles created and matched
- Collect user feedback on detection accuracy
- Monitor logs for errors or warnings
- Check storage file (profiles) for updates
- Test with real power measurements (not mock)
For issues or questions:
- Check debug logs:
configuration.yamlwith debug level - Review IMPLEMENTATION.md for architecture
- Search for error messages in logs
- Test with mock socket to isolate issue
User Docs
Reference
Development
Repository