v0.4.3.1
0.4.3.1 - 2026-03-16
✨ Features
- Trim Cycle Service: Added a new
trim_cycleHA service call that trims a cycle's stored power trace to a user-specified[trim_start_s, trim_end_s]window. Offsets are renormalized to start at zero, and all cycle metadata —start_time,end_time,duration,signature,sampling_interval— is recomputed and persisted atomically. Useful for removing noisy preamble or lingering standby readings from a recorded cycle. - Trim Cycle UI: Added a "Trim Cycle Data" action under Manage Cycles in the options flow. The UI presents an SVG preview of the full power curve with the kept region highlighted, and separate steps for setting the trim start and end points in whole minutes. Changes can be previewed, reset, and applied without leaving the interface.
🛠️ Improvements
- Power Data Preserved for Pending Feedback: Cycles that have an open feedback request are now exempted from the periodic power-data strip pass in
ProfileStore. Previously, the background cleanup could remove the stored power trace before the user had reviewed the feedback dialog, causing the SVG comparison chart to show no data. Pending cycles are identified by their presence inpending_feedbackand are skipped unconditionally until feedback is resolved. - Streamlined Power Data Decompression: Replaced a duplicate inline decompression loop in
ProfileStorewith a call to the shareddecompress_power_data()utility. The utility correctly handles both the legacy ISO-timestamp format and the newer relative-offset format, removing a subtle inconsistency where the old inline code only handled one variant. - Translation Overhaul: Comprehensively reviewed and rewrote all 60 non-English translation files. Machine-translated strings that were semantically incorrect, awkward, or technically wrong have been replaced with idiomatic translations. Common fixes applied across languages include: missing
{suggestions_count}placeholders in settings descriptions; translated JSON parameter key names inapply_suggestions(keys must stay in English); translated MDI icon names; nonsensical state labels (e.g. "jogging" for "running", "country" for "device state", "fire/combustion" for notification trigger); and leftover untranslated English strings.sr-Latn.jsonwas fully rewritten from scratch — the previous file contained Serbian Cyrillic script instead of Latin script. - Full Diagnostics Export: The HA diagnostics download now returns the complete store export — all profiles (including power samples), all past cycles, envelopes, feedback history, auto-adjustments, suggestions, custom phases, and full
entry_data/entry_optionsconfig. Previously it returned only counts and a single-cycle summary, making it nearly useless for debugging. Personally identifiable fields (power_sensor,notify_service,notify_people,name,unique_id, etc.) are still redacted. - Unix Timestamp Format Recognition:
detect_power_data_formatnow identifies absolute Unix epoch timestamps (> 1e8) as theunix_timestampvariant rather than silently discarding them.migrate_power_data_to_offsetsaccepts this format and converts epoch-based traces to relative offsets by subtracting the cycle start time, so imported or externally generated power traces are handled correctly without data loss. - Translated Service Errors: Service validation errors in
trim_cycle(device not found, integration not loaded, cycle missing, invalid trim range, empty trim window) now raiseServiceValidationErrorwithtranslation_domainandtranslation_keyinstead of plainValueErrorstrings, giving users localized error messages in automations and the developer tools panel. - SVG Safety and Robustness: HTML special characters in SVG titles and no-data labels are now escaped, preventing rendering artefacts when cycle names contain
&,<, or>. The "no power data" placeholder in merge-preview and trim-preview SVGs is now a configurable parameter rather than a hardcoded English string, enabling full localization. - Per-Device Logging Extended:
DeviceLoggerAdaptercoverage extended toProfileStoreandCycleRecorder. All log messages from these components now carry the device name prefix, consistent with the rest of the engine. - Removed Stub UI Option: Removed the "Label Multiple Cycles" entry from the Manage Cycles menu. The option was listed in the UI but had no backing implementation, leading to a silent no-op when selected.
🐛 Bug Fixes
-
Trim Offsets: Negative Input Clamping:
handle_trim_cyclein__init__.pynow clamps bothtrim_start_sandtrim_end_stomax(0.0, ...)before the range-validity check. Previously a negative input bypassed thetrim_invalid_rangeguard and was forwarded to the store unchanged. -
Envelope Persistence After Startup Repair:
async_loadnow callsawait self.async_save()a second time afterasync_rebuild_all_envelopes()completes. Previously, rebuilt envelopes were applied toself._datain memory but never written to durable storage; a subsequent restart would redo the repair and lose any downstream use of the rebuilt data. -
start_timeString Validation inadd_cycle: Stringstart_timevalues are now validated withdt_util.parse_datetime()(falling back to a float conversion attempt) before being stored as canonical ISO timestamps. Previously any non-empty string passed through unconditionally, so a malformed or placeholder value could reachpower_data_to_offsetsand corrupt the stored offset array. -
Test Alignment with
_cleanintest_trailing_zero_impact:duration_beforeand then_trailing == len(…) - len(trimmed)assertion now operate on_clean(pd)rather than the rawpdlist. Malformed rows filtered by_cleaninside_trim_trailing/_trailing_zero_countcaused length mismatches and potential index errors when real-world cycle files contained non-numeric entries. -
lt.jsonSmart-Quote Corruption: The Lithuanian translation file had itstrim_cycleservices block committed with Unicode curly quotes ("/") used as JSON structural delimiters instead of ASCII". This produced anInvalid JSONerror at startup. The block was rewritten with correct ASCII quoting while preserving the Lithuanian„…"content quotes inside string values. -
Profile Statistics Graph Flat Line: Fixed a bug where newly detected cycles showed a flat line at zero and
0.00 kWhin the Profile Statistics graph. The cycle storage routine (_add_cycle_data) incorrectly treated already-converted offset values ([seconds, power]) as unix timestamps, subtracting the cycle start unix timestamp from them a second time. This produced large negative offsets (≈ −1.7 billion seconds) that causednp.interpin the envelope builder to extrapolate to the boundary power value (typically ~0 W) across the entire time grid, rendering a flat zero curve regardless of actual power draw. -
Automatic Recovery of Corrupted Cycles: On startup, the integration now automatically detects and repairs any cycles stored with the corrupted negative offsets (first offset < −10⁸ s is physically impossible for an appliance cycle). The original offsets are recovered by adding the cycle's
start_timeunix timestamp back. Affected cycles are repaired in-place and saved transparently — no manual action required.