v1.0.5: Code quality, performance, and stability improvements (#26-#40)#42
Merged
Conversation
- Sync all code from dev repo (yearly seeding, flow card, tests) - Add sem-flow-card with reverse/invert toggles - Add yearly sensor seeding from HA recorder (#21) - Add 16 new tests for flow card injection and cleanup (#19) - Update manifest.json to point to sem-community - Add issue redirect template for community users - Update .gitignore for dev-only files - Remove orphaned root-level shims This repo is now the primary development AND HACS distribution repo. Issues migrated from traktore-org/solar_energy_management. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
load_device_discovery.py, load_management.py, dashboard_generator.py are backward-compat shims that __init__.py imports from. utility_signals.py is actual runtime code. Also removed dashboard_generator.py from .gitignore (it's needed). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The dev repo used 2.7.x versioning — sem-community uses its own versioning starting from 1.0.0. This release includes flow card, yearly seeding, and test coverage. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend battery discharge control auto-detection to support: - SolAX (solax-modbus) - DEYE / Sunsynk (ha-solarman) - Growatt - Sofar - Solis - Generic fallback (discharge_power_limit) Also remove hardcoded KEBA sensor defaults from sensor_reader (users must configure or auto-detect via config flow). 5 new test cases for platform-specific detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New sensors: - sensor.sem_battery_cycles_estimated — lifetime throughput / capacity - sensor.sem_battery_health_score — estimated capacity retention % Dashboard: Battery Health card on System tab showing health, cycles, daily charge/discharge, temperature, and SOC. Also restored TROUBLESHOOTING.md and USER_GUIDE.md removed during repo migration. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Renamed _should_reenable_keba() → _should_reenable_charger() with updated docstring. The stall detection logic is already generic (works with any charger) — the method name was the only KEBA-specific part. The CurrentControlDevice class already abstracts charger control via the charger_service parameter — no structural changes needed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- test_dashboard_generator: set hass.data={} (real dict, not MagicMock)
so DOMAIN lookup and .items() work correctly
- test_ev_energy_fix: update KEBA auto-detect test to expect None
(auto-detection removed in #5)
- test_yearly_seeding: fix sys.modules patching — include parent
recorder module for dynamic import to work
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add Battery Health card to Battery tab (was only on System tab) Shows health score, cycles, temperature with color-coded icon - Remove redundant Battery SOC gauge (hero + chart already show it) - Remove duplicate Battery Health card from System tab - Remove temperature from Power & Status secondary (now in health card) - Add accessibility text labels to status chips: - Battery chip: appends "Low" when SOC<30, "Full" when >80 - Peak Load card: primary title now includes "Safe/Warning/Critical" - Add error handling to EV Economics template (no data yet → friendly text) - Handle unavailable states in Battery Health template Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ig entities New number entities: - number.sem_ev_km_per_kwh (default 5.5 km/kWh, range 3-10) Replaces hardcoded "18" in Cost/100km calc (now cost × 100 / km_per_kwh) - number.sem_public_charging_rate (default 0.55 CHF/kWh, range 0-2) Replaces hardcoded 0.55 in public charging comparison Dashboard changes: - EV Economics card uses new config entities - EV Daily Progress: replaced fixed-max gauge with mushroom-template-card that shows daily/target kWh with percentage and color-coded icon (no longer truncates when target > 10 kWh) Translations updated for all 6 locales + strings.json. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…afe names - Standardize chart heights: all 24h/detail charts at 200px, Sankey at 280px (was inconsistent mix of 180/200/300) - Add Observer Mode alert at top of Home tab (conditional, only when active) Makes it obvious when system is read-only; tap navigates to Control tab - Remove hardcoded currency from entity names ev_km_per_kwh: "EV Efficiency" (was "EV Efficiency (km/kWh)") public_charging_rate: "Public Charging Rate" (was "... (CHF/kWh)") HA displays the unit separately based on user's locale/currency config Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Change Home tab status chips alignment from 'center' to 'justify' — spreads chips evenly with better wrapping behavior on narrow screens. (5 chips at center can overflow awkwardly on <400px viewports.) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ROI "How Savings Are Calculated" fold expanded by default Important context (formula, rates, lifetime impact) — shouldn't be hidden - Tariff Rates section label clarity: Display cards → "Current Import/Export Rate" (reflects live/dynamic value) Input cards → "Static Import/Export Rate" (user-set fallback) Previously both said just "Import Rate" / "Export Rate" — confusing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…95d912) Changes from upstream: - Battery split colors: pink (#f06292) charge, teal (#4db6ac) discharge - Optional inverter node (show_inverter config, default true) - Grid daily shows net import/export - Split click targets: battery SOC vs power open different histories - Grid daily text opens daily import energy history Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Inverter node moved down 25px to prevent overlap with solar node. All nodes below shifted accordingly, viewbox expanded to 800. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
generate_dashboard now: - Uses timestamp (not manifest version) for ?v= cache busting on all SEM card resources — ensures browsers reload JS after every regen - Removes orphaned resource entries for cards that no longer exist - New resources also get ?v= timestamp on creation Fixes: card JS changes not visible despite hard refresh (browser served cached ?v=1.0.4 URL until version changed). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…e8f81c) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…2ec50) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create sem-shared.js with canonical color palette, formatPower/formatEnergy utilities, animation duration calculator, and interaction timing constants. Update sem-chart-card and sem-flow-card to use shared constants with graceful fallback. Register sem-shared.js as Lovelace resource (loaded before other cards for global availability). Closes #33 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move entity ID patterns to consts/core.py as named constants: - ENTITY_OBSERVER_MODE_SWITCH, ENTITY_SOLAR_POWER, ENTITY_FORECAST_NIGHT_REDUCTION - WEATHER_ENTITY_CANDIDATES (tuple for ordered fallback) - STATE_UNKNOWN, STATE_UNAVAILABLE (replaces magic strings) Update coordinator.py and forecast_reader.py to use these constants instead of scattered string literals. Closes #36 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ackoff, error recovery (#34, #26, #27, #28) #34 Narrow exception handling: - Replace 10+ bare `except Exception` with specific types (HomeAssistantError, ServiceValidationError, ValueError, TypeError, AttributeError) - Add logging to silent `pass` blocks (price optimization fallback) - Split notification errors into data errors vs service failures #26 Cache forecast source and surplus window: - Cache detected forecast source; only re-detect if entity becomes unavailable - Cache surplus window estimate; only recalculate when forecast data changes (compare signature of remaining_kwh + peak_time) #27 Exponential backoff for EV device retry: - Replace linear 30-retry loop with exponential backoff (10s, 20s, 40s... 320s) - Validate setup success before stopping retries - Log at WARNING after 3+ failures; log final failure with actionable message #28 Error recovery for battery protection and load management: - Reset battery_protection_active on service call failure (prevents stale state) - Separate service errors from data errors in load management Closes #34, #26, #27, #28 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…, #31, #38) #30 Memory leaks and DOM thrashing: - sem-period-selector-card: add disconnectedCallback with button listener cleanup - sem-system-diagram-card: add animation frame cleanup to disconnectedCallback - sem-flow-card & sem-system-diagram-card: debounce _updateFlows() with 100ms timer - Clean up timers in disconnectedCallback to prevent orphaned timeouts #31 Accessibility support: - sem-period-selector-card: add role="button", aria-label, aria-pressed to buttons - sem-system-diagram-card: add role="img" and descriptive aria-label to SVG #38 Entity error states: - sem-system-diagram-card: track entity availability across 6 core sensors, display warning indicator when sensors are unavailable/unknown Closes #30, #31, #38 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Storage validation: - Add _validate_energy_data() that checks all accumulators are numeric and within sane range (<100 MWh). Rejects corrupted storage with a warning and starts fresh instead of propagating bad values. - Narrow storage exception types to OSError/ValueError/TypeError Migration safety: - Wrap v1→v2 migration in try/except; on failure, log error and return False to keep original config intact instead of partial modification Closes #37 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- binary_sensor.py: Replace warning/info availability logging with debug level (transitions are normal during coordinator reconnection, the old _logged_unavailable flag never reset on entity recreation causing spam) - sensor.py: Same debug-level availability logging fix; add last_reset returning Jan 1 for yearly TOTAL sensors so HA statistics system can correctly aggregate yearly data - number.py: available property already existed (confirmed) Closes #39 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
) - Preserve user-set priorities during device discovery: mark priorities with user_set_priority flag, skip overwriting during merge - Replace hardcoded 30s discovery delay with retry approach: if fewer devices found than stored, retry up to 3 times at 15s intervals - Add _cleanup_shed_list() that removes devices from shed list when they're already off or removed, preventing stale shedding state Closes #40 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add entity existence validation for optional EV charger entity fields in both install and reconfigure flows. Non-empty entity IDs that don't exist in HA now show "entity_not_found" error instead of silently accepting invalid IDs that fail at runtime. Add translations for entity_not_found error (en, de). Closes #32 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Flap suppression: for solar charging states (which oscillate with
clouds), require state to be stable for 60s before sending notification.
Prevents 3+ notifications in 30s during variable weather.
- KEBA service validation: check has_service("notify","keba_display")
once at first use; skip silently if KEBA integration not installed
instead of catching exception every cycle.
Closes #35
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract two large blocks from _async_update_data into dedicated methods: - _update_analytics_phases(): forecast, tracker, tariff, surplus controller, device runtimes, PV analytics, energy assistant, utility signals (~120 lines) - _send_notifications(): state-change and event-based notifications (~45 lines) The main update method now reads as a clear pipeline: read sensors → calculate energy/flows → EV control → battery protection → load management → analytics → build data → notifications → persist. Each phase is independently testable. Closes #29 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add state validation for optional entity IDs in the EV charger config step: entities that exist but report "unknown" or "unavailable" now trigger a warning log so the user is aware of potential issues at setup time. The config flow already validates: - Energy Dashboard completeness (abort if missing components) - Required EV sensors exist and are valid (via HardwareDetector) - Optional entity IDs exist in HA (entity_not_found error) Closes #32 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Test plan
Closes #26, #27, #28, #29, #30, #31, #32, #33, #34, #35, #36, #37, #38, #39, #40, #41
🤖 Generated with Claude Code