Skip to content

v0.4.3.1

Choose a tag to compare

@3dg1luk43 3dg1luk43 released this 17 Mar 10:28
7e00459

0.4.3.1 - 2026-03-16

✨ Features

  • Trim Cycle Service: Added a new trim_cycle HA 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 in pending_feedback and are skipped unconditionally until feedback is resolved.
  • Streamlined Power Data Decompression: Replaced a duplicate inline decompression loop in ProfileStore with a call to the shared decompress_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 in apply_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.json was 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_options config. 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_format now identifies absolute Unix epoch timestamps (> 1e8) as the unix_timestamp variant rather than silently discarding them. migrate_power_data_to_offsets accepts 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 raise ServiceValidationError with translation_domain and translation_key instead of plain ValueError strings, 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: DeviceLoggerAdapter coverage extended to ProfileStore and CycleRecorder. 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_cycle in __init__.py now clamps both trim_start_s and trim_end_s to max(0.0, ...) before the range-validity check. Previously a negative input bypassed the trim_invalid_range guard and was forwarded to the store unchanged.

  • Envelope Persistence After Startup Repair: async_load now calls await self.async_save() a second time after async_rebuild_all_envelopes() completes. Previously, rebuilt envelopes were applied to self._data in memory but never written to durable storage; a subsequent restart would redo the repair and lose any downstream use of the rebuilt data.

  • start_time String Validation in add_cycle: String start_time values are now validated with dt_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 reach power_data_to_offsets and corrupt the stored offset array.

  • Test Alignment with _clean in test_trailing_zero_impact: duration_before and the n_trailing == len(…) - len(trimmed) assertion now operate on _clean(pd) rather than the raw pd list. Malformed rows filtered by _clean inside _trim_trailing / _trailing_zero_count caused length mismatches and potential index errors when real-world cycle files contained non-numeric entries.

  • lt.json Smart-Quote Corruption: The Lithuanian translation file had its trim_cycle services block committed with Unicode curly quotes (" / ") used as JSON structural delimiters instead of ASCII ". This produced an Invalid JSON error 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 kWh in 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 caused np.interp in 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_time unix timestamp back. Affected cycles are repaired in-place and saved transparently — no manual action required.