Skip to content

Developer Tools

3dg1luk43 edited this page Aug 20, 2026 · 2 revisions

Development Tools

Note: Some examples use "washer" in topic/entity names, but the same tooling applies to other predictable-cycle appliances (e.g., dryers and dishwashers).

See Testing for comprehensive documentation.

All testing and mock socket documentation has been consolidated into Testing:

  • Mock socket reference & parameters
  • Fault injection scenarios
  • Testing procedures
  • Debugging guide

Quick Start

cd /root/ha_washdata/devtools
pip install paho-mqtt
python3 mqtt_mock_socket.py --speedup 720

In another terminal:

mosquitto_pub -t homeassistant/mock_washer_power/cmd -m 'LONG'

See https://github.com/3dg1luk43/ha_washdata/wiki/Testing#mock-socket-reference for full documentation.


Releasing (release_check.sh)

The panel is a generated artifact. custom_components/ha_washdata/www/ha-washdata-panel.js is the source of truth; devtools/build_panel.mjs minifies it into ha-washdata-panel.min.js and records the source hashes in build-manifest.json. frontend.py serves the minified file only while the recorded hash still matches the source on disk, so a forgotten rebuild degrades to the larger readable file rather than serving stale code.

That fails safe, but it does not fail loudly: a release built from a stale bundle silently loses the ~32% size win for every user. devtools/release_check.sh is the gate.

# Verify everything a release needs (this is also what CI runs)
devtools/release_check.sh

# Regenerate the artifacts instead of just failing on them
devtools/release_check.sh --fix

# Add the slow suite, the E2E suite, and E2E against the minified bundle
devtools/release_check.sh --full

# Also require the tag to agree with manifest.json
devtools/release_check.sh --tag v0.5.5

It exits with the number of failed checks, and every failure prints the command that fixes it. What it checks:

Check Why it matters
*.min.js + build-manifest.json match their sources Also enforced by tests/test_panel_build.py and the CI generated-artifacts job; this is the local pre-tag copy of that gate. The runtime only ever falls back to the bigger file, so nothing breaks to tell you
ws-types.d.ts + docs/WS_API.md match ws_schema.py Generated from the schema; drift means the published contract is wrong
manifest.json version == top CHANGELOG.md heading (== --tag) The version HACS reports, the version humans read, and the version GitHub publishes are three separate strings
strings.json == translations/en.json Project invariant for the HA key namespace
Every shipped .json parses One malformed translation file breaks startup for that locale
No leading/trailing whitespace in translation values Home Assistant's own validator rejects it
Python compiles, panel + card JS parse, panel render smoke A backtick in panel CSS blanks the panel at runtime and only the smoke test sees it
Fast pytest suite (--full adds slow + E2E)
The build artifacts are tracked by git They are served to users, so an untracked artifact never ships at all

Release procedure

  1. Bump custom_components/ha_washdata/manifest.json version to match the new ## <version> heading in CHANGELOG.md. Do this first: every run of the script checks the two against each other, so doing it later means step 2 reports a version failure you already know about.
  2. devtools/release_check.sh --fix - rebuilds the bundles and regenerates the WS artifacts.
  3. devtools/release_check.sh --full --tag <version> - must exit 0.
  4. Commit including www/*.min.js and www/build-manifest.json. They are build outputs but they are the files users download, so they are committed deliberately.
  5. Tag and push. The Release Preflight workflow re-runs the same checks against the tag, so a mismatch is caught even if step 3 was skipped.

CI

  • Tests (.github/workflows/tests.yml) runs on every push and PR: the fast pytest suite, the generated-artifact checks, the panel smoke test, and the E2E suite both against the readable source and against the minified bundle. The second E2E run is not redundant - a minifier that renamed something the panel reaches by name would pass every other check.
  • Release Preflight (.github/workflows/release_preflight.yml) runs on a pushed tag and enforces the version agreement that only exists at release time.

Slow tests are deliberately not in CI: they replay real traces from cycle_data/, which is gitignored and therefore absent on a runner. Run them locally (./run_tests.sh --slow) or via release_check.sh --full.


Diagnostic Analyser (analyze_diag.py)

Analyses a WashData diagnostic export (JSON) and compares the device's current settings against optimal settings derived from its own cycle history. Uses the same heuristics as the in-HA suggestion engine but runs fully offline - no Home Assistant required.

Usage

# From the repository root with the venv activated:
source .venv/bin/activate

# Pass the export file as an argument
python3 devtools/analyze_diag.py path/to/diagnostics_export.json

# Or let it prompt you interactively
python3 devtools/analyze_diag.py

# Plain text output (no ANSI colours - good for CI or piping)
python3 devtools/analyze_diag.py --no-color export.json

What it produces

Section Parameters analysed
Power Thresholds stop_threshold_w, start_threshold_w, running_dead_zone
Energy Gates end_energy_threshold, start_energy_threshold
Timing & Operational watchdog_interval, no_update_active_timeout, off_delay, min_off_gap, profile_match_interval
Matching & Learning duration_tolerance, profile_duration_tolerance, min/max_duration_ratio

Each row shows the current value, suggested value, a % change arrow, and a one-line rationale. A summary at the end lists how many parameters can be improved and where to apply them in the HA UI.

The report also surfaces any suggestions already computed by live HA operation (stored in manager_state.suggestions inside the export) alongside the offline analysis - useful for cross-checking.

A Cycle History table at the bottom lists every detected programme with its average duration, standard deviation, and coefficient of variation so you can immediately see which programmes are consistently recognised vs. which are noisy.

How to get a diagnostic export

  1. In Home Assistant go to Settings → Devices & Services → WashData.
  2. Click the three-dot menu on the device card and choose Download Diagnostics.
  3. Pass the downloaded .json file to analyze_diag.py.

Clone this wiki locally