github rwoldberg/ldata-ha v2.1.2
Code Refactor and Minor Bug Fixes

pre-release22 hours ago

This release is mainly Refactoring code with minor bug fixes.

Why Refactor? think of it like cleaning the kitchen while you cook. You aren't changing the menu or serving a new dish; you're just making sure the workspace is organized so you don't trip over a drawer or lose the salt when things get busy.

Architecture

  • Extracted API layer into api/ package — http_client.py, websocket_client.py, exceptions.py with re-exports from init.py
  • ldata_service.py now focuses on data orchestration; transport concerns are isolated

Massive API Call Reduction & Wi-Fi Stability

  • 98.3% Reduction in Cloud Traffic: Shifted the integration's primary data source to the event-driven WebSocket stream. Background REST API polling for V2 (WHEMS) panels has plummeted from ~7,200 calls/day down to just ~120 calls/day.
  • Eliminated Network Stress: Removed the aggressive 60-second bandwidth toggle (which forced the panel to drop/rebuild its cloud connection constantly). This completely resolves transient 0W spikes and 6-minute WebSocket data lockups.
  • Hourly Hardware Sync: The heavy polling loop (Panel RSSI + CT Energy fetch + Bandwidth Toggle) now runs on a strict 1-hour timer to cleanly sync hardware data without overwhelming the panel.

Real-Time "Sensor Fusion" (Riemann Sums)

  • Sub-Second Energy Dashboards: The Leviton cloud only pushes lifetime kWh updates every ~15 minutes, causing blocky dashboards. The integration now features a local Riemann Sum Integrator that calculates instantaneous kWh based on the high-speed Wattage stream.
  • Smooth True-Ups: Every 1 hour, the integration fetches the exact hardware lifetime counters from the panel and seamlessly absorbs the difference into the software drift. Dashboards never freeze or jump backward.

New entities / Options

  • Breaker Daily Import sensor — only created for breakers with non-zero import (solar detection: skipped when consumption > 0 and import == 0)
  • Blink LED switch per breaker — diagnostic category, controllable via PUT /ResidentialBreakers/{id} with {"blinkLED": true/false}, always created (not gated on breaker control)
  • Breaker ID shown in device info via serial_number field
  • Added new "Log Raw Websocket String" option

Bug fixes

  • Removed Zero-Transition Protection as no longer needed
  • ClientConnectionResetError on WS subscription sends — _ws_send_subscriptions now guards ws.closed and catches connection resets cleanly
  • Fire-and-forget heartbeat task now tracked and cancelled on disconnect
  • Panel hardware field now uses panel_type instead of hardcoded "LDATA"
  • Added CT clamp channel # to Device info an log warnings if not configured
  • Clarified naming of "Three Phase" option as it was misleading.
  • Clarified naming of "Log Full Websocket Data" to "Log All Parsed Data" option as it was misleading.

Entity cleanup

  • All listener registrations moved from init to async_added_to_hass across all sensor, binary sensor, and switch classes
  • Breaker Status binary sensor moved to Diagnostic category
  • Cloud Connected sensor moved to DIAGNOSTIC group
  • BLE RSSI sensor has 5 dBm deadband filter to reduce DB writes
  • Removed unused _LEG2_POSITIONS from const.py

Code quality

  • Consistent aiohttp.ClientTimeout(total=N) across all HTTP calls
  • Lazy % logging in coordinator (was f-strings)
  • Logger name consistency — API modules use LOGGER_NAME from const.py instead of hardcoded strings
  • Silent except Exception: pass handlers replaced with _LOGGER.debug throughout http_client.py and ldata_service.py

Don't miss a new ldata-ha release

NewReleases is sending notifications on new releases.