Changelog¶
All notable changes to this project will be documented in this file. The format is based on Keep a Changelog.
[Unreleased]¶
[0.1.69] - 2026-10-17¶
Authoritative §14a readout plus config-flow diagnostic refinement. One new diagnostic entity and two new attributes on the existing §14a sensors; no change to existing automations.
Added¶
sensor.<meter>_enwg14a_module— ENUM diagnostic on the meter sub-device. States:none/module_1/module_3/unknown. Backed by SDK v1.1.8'sSiteSystemInfo.enwg14a_modulefrom the dedicated/api/v1/sites/{id}/system-infoendpoint. Separate from the existing heartbeat-window-basedmodule1_grid_fee_reduction_annualandmodule3_grid_fee_savings_annualsensors.
Changed¶
- Added
enwg14a_module_valid_fromattribute (ISO-8601 date) to both existing §14a sensors (Modul 1 reduction, Modul 3 savings) for traceability of the enrolment date. The Modul-3 sensor additionally gains thevariable_grid_fee_eur_per_kwhattribute as the HT/NT counterpart to the already-mappedcomparison_grid_fee_eur_per_kwh. - Bumped the
onekommafiveSDK pin to>=1.1.8,<2(from>=1.1.7,<2). v1.1.8 adds/api/v1/sites/{id}/system-info(SiteSystemInfo.enwg14a_module) and the per-windowHeartbeatPriceWindow.variable_grid_fee_eur_per_kwhfield consumed above. - Shorter config-flow failure WARNING line. v0.1.68 included the full response body in the WARNING, which turned out to be a ~68 KB Auth0 Universal Login HTML page when step 2 of the OAuth2/PKCE login rejects credentials. The line now reduces HTML bodies to their
<title>plus the byte count (Login failed: 1KOMMA5° Sign-in [HTML body suppressed, N bytes]); non-HTML bodies above 300 chars are clipped with a[truncated, N bytes total]tag. Messages without the<label>: <body>shape pass through unchanged. See Issue #37 for the signal this refines.
[0.1.68] - 2026-10-10¶
SDK pin bump plus a diagnostic log line for failed logins. No new entities, services or configuration surfaces; no change to existing automations.
Changed¶
- Bumped the
onekommafiveSDK pin to>=1.1.7,<2(from>=1.1.6,<2). v1.1.7 addsNotification.updated_at: str | None— the ISO-8601 timestamp of the last read/dismissed state change on/users/{uid}/notifications/latest. Additive,Noneon notifications that have never changed state after creation. The new field flows through theonekommafive_notificationbus event for anyone who wants to key on it. - Config-flow login failures now emit a WARNING line with the SDK's error context (which OAuth2/PKCE step failed and the raw HTTP body or status). Users still see the generic
invalid_authorcannot_connectform; operators get the detail inhome-assistant.logto tell "wrong credentials" apart from "account not in this Auth0 tenant" or "network error". No change for successful logins.
[0.1.67] - 2026-10-10¶
Adds three Diagnostic Sensoren for the Vertragsübersicht — active contracts (PII-safe), add-on eligibility, and the EMP backend — plus a new §14a-Modul-3 grid-fee-savings sensor on the meter sub-device. Also bumps the SDK floor to the version carrying both endpoints. No change to existing automations.
Added¶
sensor.<sys>_active_subscriptions— number ofstatus == "ACTIVE"contracts;contractsattribute carries each subscription's PII-safe fields (type,status,start_date,end_date,signed_date, notice period,renewal,billing_frequency,price_eur,currency,payment_method,country_code). The raw CRM record (customer_id,site_id,electricity_contract_number,market_location_id,terms_and_conditions_url,raw-Blob mit IBAN) stays out by whitelist. Diagnostic entity category.sensor.<sys>_subscription_eligibility— number of 1KOMMA5°Care add-ons the account qualifies for; attributes split intoeligible(product types) andineligible({type, reason}with the CRM-provided reason verbatim). Reads SDK v1.1.4'sget_subscription_eligibility().sensor.<sys>_emp_backend— ENUM diagnostic sensor (gridx/1k5/unknown) exposing the account's EMP backend. Previously only visible in the diagnostics dump. Options stay lowercase to satisfy hassfest's translation-key pattern; translations map each key to its display label (gridx→ "GridX",1k5→ "1KOMMA5°").sensor.<meter>_module3_grid_fee_savings_annual— annual net savings from variable Netzentgelte (HT/NT per BK6-22-300), parented to the meter sub-device alongside the existing Modul-1 sensor. ReadsHeartbeatPriceWindow.module3_total_savings_eurfrom the yearly window. Staysunavailableuntil the site opts into Modul 3. Attributes expose the flat reference tariff, the comparison vs. variable fee totals, the combined Modul-1-plus-Modul-3 savings, the derived gross estimate (× 1.19) and the basis string. Diagnostic category.
Changed¶
- Bumped the
onekommafiveSDK pin to>=1.1.6,<2(from>=1.1.3,<2). v1.1.4 addsSystem.get_subscription_eligibility()— the endpoint behind the newsubscription_eligibilitysensor above. v1.1.5 addsSystemDetails.external_partner_id/SiteDetails.external_partner_id(additive,Nonefor consumer-direct accounts). v1.1.6 adds fiveHeartbeatPriceWindowattributes for §14a-Modul-3 (variable Netzentgelte HT/NT per BK6-22-300):comparison_grid_fee_eur_per_kwh,comparison_grid_fees_total_eur,variable_grid_fees_total_eur,module3_total_savings_eur,enwg14a_total_savings_eur(allNoneuntil the site opts in).
Internal (no user-visible change)¶
- Property-based tests (
hypothesis) on three pure-logic helpers (get_current_price,trapezoidal_delta_kwh,find_cheapest_window), 100–200 random examples per property. - Device- and entity-registry snapshot tests across four setup scenarios (GRIDX / 1K5 backend, with/without heat pump, with/without wallbox) pin the sub-device hierarchy at build time.
- Docstring-coverage gate via
interrogate(pre-commit + CI,--fail-under 85, baseline 86.7 %). - Mutation testing (
mutmut) onhelpers.py+sensor_entities.py, opt-in workflow onmainpushes and manual dispatch; results surfaced as a job summary and 30-day artifact. - Nightly matrix across
python {3.13, 3.14}×homeassistant {stable, beta}catches core-level breaking changes before user issues; failures open a singlenightly-regressionissue.
[0.1.66] - 2026-10-03¶
Adds a new §14a-Modul-1 meter sensor plus the usual internal hygiene: SDK pin bump, Ruff-line-length convergence to the Home-Assistant-core standard, and multi-EV dashboard documentation.
Added¶
sensor.<sys>_meter_module1_grid_fee_reduction_annual— annual net §14a-EnWG Modul 1 grid-fee reduction (EUR/year), parented on the meter sub-device. ReadsHeartbeatPriceWindow.module1_savings_per_year_eurfrom the SDK'sget_heartbeat_pricesendpoint. Staysunavailablewhen the account carries no provisioning date (sites without iMSys + a controllable consumption device see no sensor value, which is semantically correct). Diagnostic category keeps it out of the main device card. Attributes:provisioning_date(ISO),active_days,gross_estimate_eur_assumption(value × 1.19, flagged as an assumption pending a second-grid-area data point), andbasisnaming the BNetzA BK6-22-300 regulation. The electricity-cost and feed-in-revenue sensors are deliberately left untouched: Modul 1 is an annual grid-fee rebate, not a per-kWh discount.- New
heartbeat_pricescoordinator on a 1 h cadence, backing the sensor above.onekommafive.refresh_nowacceptscoordinator: heartbeat_prices; asensor.<sys>_diag_heartbeat_prices_updatetimestamp joins the diagnostic-timestamp set. - Four more AI-optimization decision binaries cover the remaining actionable decisions from the SDK enum:
binary_sensor.<sys>_optimization_battery_grid_discharge(BATTERY_DISCHARGE_TO_GRID),binary_sensor.<sys>_optimization_battery_no_charge(BATTERY_NO_CHARGE),binary_sensor.<sys>_optimization_battery_no_discharge(BATTERY_NO_DISCHARGE), all parented on the inverter sub-device; plusbinary_sensor.<sys>_optimization_ev_grid_charge(EV_CHARGE_FROM_GRID) on the wallbox sub-device.HEATPUMP_AUTOstays out as the no-op default. Automations trigger directly on the matching decision instead of parsing the enum text sensor.
Changed¶
- Bumped the
onekommafiveSDK pin to>=1.1.3,<2(from>=1.0.3,<2). v1.1.1 sendsview=historicwithSystem.get_optimizationsin preparation for the 1KOMMA5° endpoint enforcing the parameter; without it, once enforcement lands, the response would collapse to an emptyeventslist without a warning. As of 2026-09-28 the endpoint still returns identical payloads with and without the parameter, so no existing install sees a regression; the bump is a proactive guardrail. v1.1.1 additionally introducesSystem.get_live_optimizations()for the currently running optimisation slot (not consumed by the integration yet). v1.1.2 adds fourmodule1_*fields onHeartbeatPriceWindow(provisioning date, active days, per-year / total net savings), which v1.1.3 documents as the working hypothesis "§14a EnWG Modul 1 grid-fee reduction" (net figure; brutto ≈ 1.19 × net based on the first observed account). - Ruff
line-lengthlowered from 100 to 88 to match the Home Assistant core Ruff config.ruff formatreformatted 54 files (193 lines rewrapped automatically) plus 41 manual cleanups (docstring trims, inline-comment relocations, factored-out f-strings). No entity or code-path behaviour changed. .git-blame-ignore-revsadded with the two reformat SHAs sogit blamecontinues to point at the substantive authors of each line. GitHub honours the file automatically; contributors enable it locally once withgit config blame.ignoreRevsFile .git-blame-ignore-revs(documented inCONTRIBUTING.md).- Example dashboards (
dashboard/dashboard.yaml,dashboard/dashboard-showcase.yaml) now stack the Fahrzeug view as Wallbox-Assignment → Lademodus → Smart-Charge-Einstellungen, with per-EV conditional blocks so multi-vehicle setups show the currently-assigned EV's controls. Placeholders switch from the singleCAR_IDENTIFIERtoEV_N_PREFIX/EV_N_SLUG, one duplication per EV; the fahrzeug-view screenshot indashboard/README.mdis updated.
[0.1.65] - 2026-09-26¶
Consolidates the v0.1.63-armed feature work with the SDK v1.0.2 async migration; the v0.1.63 tag was skipped so both stories ship together.
Added¶
select.<sys>_<wallbox>_assigned_vehicle— bind a vehicle profile to a wallbox from Home Assistant (feature request #24). Options are the site's vehicles; selecting flips the assignment via the SDK's asyncEVCharger.assign_charger. 1:1 exclusive per 1KOMMA5°'s model — the previously bound vehicle is released automatically. Single-vehicle sites see the entity but have nothing to switch.- Service
onekommafive.assign_ev_to_wallbox— id-addressed counterpart to the select entity for scripts. Schema:wallbox_id,ev_id(both required); returns{success, previous_ev_id}. - Automation blueprint
vehicle_at_wallbox.yaml— one automation per vehicle. Trigger = the vehicle's plug-in binary sensor; action = flip the wallbox select. - Example dashboards (
dashboard.yaml,dashboard-showcase.yaml) gain a Wallbox → Fahrzeug card in the EV view. - Live coordinator surfaces the wallbox inventory with live
assigned_ev_idat the 30-second cadence, so App→HA assignment changes reach HA within one tick instead of five minutes.
Fixed¶
sensor.<sys>_optimization_event_countcounts logical 15-minute slots instead of API event objects. The/heartbeat-ai/optimizationsendpoint aggregates consecutive same-decision slots into a single event, so counting objects silently under-reported the day's decision volume by up to a factor of four.binary_sensor.<sys>_optimization_battery_grid_chargeandbinary_sensor.<sys>_heatpump_recommendationstayonfor the full aggregated slot span (uses SDKend_time; falls back toto_timeon older payloads).
Changed¶
- Migrated to the async
onekommafiveSDK v1.0.2. Every 1KOMMA5° API call now runs on Home Assistant's aiohttp loop; the previoushass.async_add_executor_jobwraps around SDK calls are gone. The integration shares HA's global aiohttp session viahomeassistant.helpers.aiohttp_client.async_get_clientsession, so a single connection pool serves both HA and the 1KOMMA5° API. No user-visible change to entities, services, or blueprints. - All seven data coordinators, both service handlers (
refresh_now,get_heartbeat_metrics,assign_ev_to_wallbox,get_cheapest_window,get_most_expensive_window), the four write-path platforms (switch, select, number, time), the diagnostics dump and the config-flow authentication path all run natively async against the new SDK. - Setup now uses the SDK's first-class
get_price_guarantee(customer_id)endpoint instead of iterating the subscriptions list; behaviour unchanged. - SDK type annotations replace the previous
Anyplaceholders on the SDK boundary. Thepy.typed-marked SDK gives mypy the full model surface; the integration's own dataclasses (OneKomma5Data,LiveData,PriceData,SystemStatusData,OptimizationData,NotificationsData,EnergyTodayData,WeatherData) now carry concrete SDK types. - Bumped the
onekommafiveSDK pin to>=1.0.3,<2(from>=0.5.0,<0.6). v1.0.2 loosened the aiohttp constraint to>=3.10,<4, matching Home Assistant's own aiohttp 3.13.3 requirement; v1.0.3 is the current maintenance release picked up automatically at install time. attributes.toonsensor.<sys>_optimization_last_decisionand on thedecisions[]entries undersensor.<sys>_optimization_event_countnow reflects the aggregated slot-span end. Newslot_countattribute exposes how many 15-min slots the decision covers.- Bus event
onekommafive_optimization_decisiongainsend(aggregated span end) andslot_countfields alongside the existingto(first-slot end, kept for compatibility).
Quality-scale hardening¶
- Combined test coverage lifted from 93 % to 95.4 % (292 tests, +25). CI
--cov-fail-undergate raised from 90 to 95; helpers.py, system_health.py and diagnostics.py reach 100 %. pyproject.toml [tool.mypy]switches tostrict = true. Eleven remaining strict errors resolved (typed generics, explicitbool/float | Nonecasts on properties, HA-stub# type: ignore[attr-defined]markers forWeatherEntityFeatureand switchDOMAIN).
Refactor sweep¶
- HA best practice: named the wallbox-reload task (
onekommafive_reload_on_wallbox_change) so HA 2024.5+ no longer warns; markedactive_features,details_flaganddynamic_pulse_price_guaranteesensors asEntityCategory.DIAGNOSTIC(static contract flags, not live automation signals); made_SystemEntryafrozen=Truedataclass. - Clean code:
OneKomma5Data.named_coordinators()is now the single source of truth for the seven coordinator labels (services and system-health drop their duplicate maps);_null_safedecorator centralises theif data is None: return {}guard across the diagnostics summarisers; dead_redact_assetwrapper and unusedATTR_SYSTEM_ID/ATTR_SYSTEM_NAMEconstants gone; five function-local imports in__init__.pyandChargingModein select/number hoisted to module level;_BaseSystemEntityrenamed toSystemEntityBase(public intra-package base). - KISS:
QuarterHourUpdateMixinand_DescriptionValueSensortype themselves underTYPE_CHECKINGand drop four# type: ignore[attr-defined]markers;OneKomma5PriceCoordinator._fetchsplits into_fetch_today_and_tomorrow(SDK round-trip) and_price_statistics(dict summary), shrinking the entry-point from 61 to 15 lines with identical behaviour.
[0.1.63] - never tagged¶
The v0.1.63 armed work (wallbox → vehicle assignment, live-coordinator wallbox fetch, optimization slot-count fix) was consolidated into v0.1.65 and shipped there on 2026-09-26; see the [0.1.65] entry above.
[0.1.61] - 2026-09-24¶
Fixed¶
sensor.<sys>_optimization_last_decisionnow surfaces theBATTERY_DISCHARGE_TO_GRIDdecision instead of degrading tounknownwith a warning. The 1KOMMA5° API emits this decision when the battery discharges into the grid at high spot prices; first surfaced in issue #23. Added the value to_KNOWN_DECISIONSand to the sensor's ENUMoptions, translated in all seven locales.
[0.1.60] - 2026-09-20¶
Added¶
- Diagnostics:
system.device_gateways[]block. Support requests can now readtype,installer_nameandinstallation_dateper Heartbeat gateway from the diagnostics dump. IDs, serial numbers, GridX identifiers and user identifiers stay excluded from the payload by contract.
Changed¶
- Bump the
onekommafiveSDK pin to>=0.4.0,<0.5(from>=0.3.0,<0.4). Upstream0.4.0migrates theactive-featuresendpoint from v1 to v2 (response schema unchanged) and addsSystem.get_device_gateways()as a richer standalone gateway accessor. The new endpoint drives the additions above.
[0.1.59] - 2026-09-13¶
Fixed¶
sensor.<sys>_optimization_last_decisionno longer raisesValueError: … not in the list of options providedwhen the 1KOMMA5° Cloud ships a decision enum value the sensor's ENUM options list doesn't cover. AddedEV_CHARGE_FROM_GRID(observed live 2026-09-11) to the list and hardened the value coercion so future new decisions coerce tounknown+ a one-line warning instead of crashing HA's ENUM validation. Regression test pins the behaviour.- Translated the
ev_charge_from_gridstate ofsensor.<sys>_optimization_last_decisionin all seven locales. Before this the state rendered as the raw lowercase enum. English shows "Charge EV from grid", German "E-Auto aus Netz laden", and the five remaining locales analogously.
Changed¶
- Bump the
onekommafiveSDK pin to>=0.3.0,<0.4(from>=0.2.3,<0.3). Upstream0.3.0is a KISS-cleanup release: CLI dispatch viaargparse set_defaults(func=…), deduplicated CLI subcommand bodies, hoisted test fixtures and analytics helpers, tightened docstrings. No public API change (no new endpoint, no removed field, no signature change); the major-bump reflects the cut, not a break. Integration-side: no code change needed.
[0.1.58] - 2026-09-14¶
Added¶
- Multi-wallbox support. Sites with more than one physical wallbox now get one HA sub-device per wallbox, each with its own manufacturer / model / firmware. Vehicle profiles parent under the wallbox they are actually paired to (via
Wallbox.assigned_ev_id ↔ EVCharger.assigned_charger_id), so HA's device view reads "Vehicle → Wallbox → System" for the natural relationship instead of collapsing every vehicle under the same wallbox. - Per-wallbox connectivity sensors. New
binary_sensor.<sys>_wallbox_<id>_connectedper wallbox on multi-wallbox setups. Aggregatewallbox_connected(AND over all wallboxes) stays for the default "all wallboxes healthy" gate. Single-wallbox setups do not get the per-instance sensor (would be identical to the aggregate).
Changed¶
- System-status coordinator no longer logs
Duplicate asset of type EV_CHARGER; keeping first, dropping subsequentwhen more than one wallbox is present. Multi-wallbox is a legitimate case; the full asset list is now surfaced. - Bump the
onekommafiveSDK pin to>=0.2.3,<0.3(from>=0.2.0,<0.3). Upstream0.2.1preserves the OAuth refresh token when Auth0's refresh response omits it (fixes an unlucky session-invalidation edge case that could force re-authentication).0.2.2narrows the SDK-CLI enrichment exception handler toRequestErroronly;0.2.3swaps a try/except in the enrichment path forcontextlib.suppress. No integration-side code change.
Compat¶
- Single-wallbox installs (historical default) keep the wallbox sub-device identifier
(onekommafive, <system_id>_wallbox)and the translateddevice.wallbox.namelabel. Area assignments, dashboards and device_registry references stay intact. Unique IDs and entity IDs of vehicle-related entities are unchanged across single- and multi-wallbox installs; long-term statistics, automations and Energy-Dashboard configuration keep working.
[0.1.57] - 2026-09-07¶
Fixed¶
- Diagnostics: reading the installed SDK version no longer triggers a
Detected blocking call to openwarning in the HA log. Theimportlib.metadata.version("onekommafive")call previously ran inside the diagnostics async handler and read.dist-info/METADATAfrom disk. It now runs once at setup time in the executor (alongside the other cached setup-time reads) and diagnostics just surfaces the cached value.
Added¶
- Wallbox / EV control now works on non-GridX installs (Enphase EVSE_IQ2 and other non-GridX wallboxes). The
onekommafiveSDK pin is raised to>=0.2.0,<0.3; upstream v0.2.0 migrates the wallbox and EV endpoints to the site-scoped v2 routes that work on both GridX and non-GridX backends. Previously the legacy system-scoped routes returnederror_code:30401 "DeviceGateway not found"and no charging-mode / target-SoC / departure-time entities were created. Pair a vehicle profile to the wallbox in the 1KOMMA5° app and restart Home Assistant to pick them up. - Diagnostics dump now includes the notifications coordinator alongside the other six (was silently missing).
Changed¶
- Diagnostics: the
system.wallboxes[]block drops thegridx_hardware_id_presentflag. SDK 0.2.0 removedWallbox.gridx_hardware_id, and every wallbox exposes a stableWallbox.idunder the new API, so a presence flag carried no signal. Pairing diagnostics rely onassigned_ev_id_presentas before. Theemp_type_1k5_native_hinttriage flag stays as a safety net for edge cases where the site-scoped route still fails. - EMS auto-mode switch is no longer created on
emp_type: "1K5"installs; the underlying GridX EMS endpoint is unreachable on that backend, so the switch would be permanently unavailable. If your setup used to run on the GridX backend and later moved to 1K5, the leftoverswitch.<sys>_ems_auto_modeentity is removed from the registry the first time you reload. The Repair Issueems_settings_unavailableis also skipped on these installs (and one stale copy from a previous GRIDX run gets cleared once).
[0.1.56] - 2026-09-04¶
Fixed¶
- FoxESS installs (and any install exposing a separate
BATTERYasset): the four battery sensors (battery_power,battery_soc,battery_charge_power_energy,battery_discharge_power_energy) now sit under the dedicatedbatterysub-device instead of the inverter sub-device. v0.1.54 added thebatterysub-device mapping but the entities themselves still carried the historicaldevice_key="inverter", so the battery sub-device stayed empty and never materialised. Sungrow / single-HYBRIDinstalls are unchanged — no empty battery device grown when the cloud reports no separateBATTERYasset. Unique-ids and entity-ids stable.
[0.1.55] - 2026-09-04¶
Fixed¶
- Price coordinator no longer trips the intermittent
ApiClientForwardedException: Validation failed(error_code 100006) from the market-prices endpoint. Upstream SDK 0.1.47 aligns thefrom/totimestamps to the resolution grid before the request; the v4 endpoint recently started rejectingto=23:59:59Zbecause it doesn't land on a 15-minute slot. Pin raised toonekommafive>=0.1.47,<0.2; no integration-side code change needed.
[0.1.54] - 2026-09-07¶
Added¶
- FoxESS installs now get proper sub-devices. The inverter surface now matches either the
HYBRIDasset (Sungrow etc.) or thePV_SYSTEMasset that FoxESS-and-friends emit, and a newbatterysub-device is created for theBATTERYasset (withdevice.battery.nametranslations in all 8 locales). Sungrow / single-HYBRIDinstalls unchanged. - Diagnostics dump now includes a
system.wallboxes[]section withassigned_ev_id_presentandgridx_hardware_id_presentflags per wallbox (no UUIDs leaked). Makes it possible to tell from a downloaded diagnostics file whether a vehicle profile is paired to the wallbox — the missing pairing is the most common reason the charging-mode / target-SoC / departure-time entities don't appear.
Changed¶
DeviceInfo.via_device(identifier tuple) is deprecated in HA 2026.7 and removed in HA 2027.8. All sub-device DeviceInfo objects now usevia_device_id(device_registry id string) when running on HA ≥ 2026.7 and fall back to the tuple form on older HA. No behaviour change; unique-ids and entity-ids stable. Users on HA 2026.7+ see thevia_devicedeprecation warnings foronekommafivedisappear from their logs.- Documentation: the README section on the EV charger / wallbox now spells out that the charging-mode / target-SoC / departure-time entities model the vehicle profile (SDK's
/v1/devices/evsendpoint), not the wallbox hardware. Without a vehicle profile registered in the 1KOMMA5° app under Settings → Vehicles and paired to the wallbox, no per-vehicle controls are created — the wallbox device still appears with connectivity + aggregateev_chargers_power/ev_charger_costsensors.
[0.1.53] - 2026-08-16¶
Added¶
daily_savingssensor now exposesco2_saved_kgas an attribute — lifetime CO2 avoided (kg) sourced fromsystem.get_impact_overview()at setup.
Changed¶
- Bump the
onekommafiveSDK pin to>=0.1.46,<0.2(from>=0.1.45,<0.2). Upstream 0.1.46 migrates thesites/{id}/detailsandsites/{id}/status-and-assetsendpoints from v2 to v3; payloads are byte-identical (SHA-256 verified) and no model fields changed. Proactive future-proofing against a v2 retirement. - Internal refactor sweep: setup-time SDK fetches share a
_safe_fetch(label, fn)helper (was three copies of the try/except-log-None pattern); base coordinator gains an_on_data(data)post-fetch hook so Live/Price/Optimization/Notifications drop their duplicated_async_update_dataoverrides; EV entity constructors take theevobject directly instead of unpackingid/manufacturer/modelat every call site (also drops two dead_ev_chargerfields). Behavior unchanged; unique-ids and entity-ids stable; 226 tests pass.
[0.1.52] - 2026-08-09¶
Added¶
- Notifications event bridge. New bus event
onekommafive_notificationfires for each newly-observed 1KOMMA5° cloud notification (energy market thresholds, system health alerts, dynamic-pulse events, …). Payload is a flat dict withsystem_id,notification_id,type,title,body(both already localized to the account language),locale,created_at, andmeta(e.g.meta.price.value). Enables automations that react to the same push notifications the 1KOMMA5° mobile app receives. Dedup state persists across HA restarts viahomeassistant.helpers.storage.Storeunder.storage/onekommafive.notifications.<entry_id>; the first refresh after a fresh install primes silently (no replay of history). - New diagnostic timestamp
sensor.<sys>_diag_notification_update(entity_category=diagnostic) tracks the notifications coordinator's last successful refresh. onekommafive.refresh_nowservice now acceptscoordinator: notifications(andcoordinator: allincludes it).sensor.<sys>_dynamic_pulse_price_guarantee— rawprice_guarantee_valuefrom a DYNAMIC_PULSE subscription (via SDK 0.1.44'sget_subscriptions), exposed inEUR/kWh. Informational only — the guarantee is bound to 1KOMMA5°-side terms this integration doesn't model. Sensor is only created when a DP contract is present.onekommafive.get_heartbeat_metrics(window)service — on-demand fetch of aggregated Heartbeat metrics for one ofday/week/month/half_year/year(via SDK 0.1.44'sget_heartbeat_prices). Returns a flat dict with all ~22 populated fields: PV / grid kWh, tariffs, €-amounts, VAT, plus a couple of composite fields the caller can choose to ignore. Absent windows respond{"window": ..., "available": false}so callers can branch on it. Response order follows the SDK model — useful for sanity-checking cloud-side aggregates against locally-integrated Long-Term Statistics.
Changed¶
- Bump the
onekommafiveSDK pin to>=0.1.45,<0.2(from>=0.1.43,<0.2). Upstream0.1.44addssystem.get_heartbeat_prices()andsystem.get_subscriptions(customer_id), both consumed by the two new surfaces above. Upstream0.1.45is a marginal dependency-metadata change (PyJWT[cryptography]extra split into directcryptography>=41requirement) to silence pip's cryptography-mismatch warning; no API-surface change. - Internal refactor sweep:
_resolve_config_entryhelper deduplicated across the four services that resolve a config entry,dir(win)reflection in the heartbeat-metrics handler replaced withdataclasses.asdict()(fail-loud instead of fail-silent on SDK method additions), deadPriceData.current_price_with_grid_costsandPriceData.grid_pricesfields removed (zero readers repo-wide), tomorrow-window date math simplified from a 6-linedatetime.replace(...)todt_util.start_of_local_day() + timedelta(days=1),ApiErrorandissue_registrylate imports hoisted out of hot paths, docstring / comment bloat trimmed (net -90 lines across the coordinator + service + sensor files). Behavior unchanged; 224 tests still pass. - Live power / weather / optimization sensors share a new
_DescriptionValueSensormixin instead of hand-rolling the samenative_value = description.value_fn(coord.data)guard three times.OneKomma5PriceSensorandOneKomma5EVSensorstay bespoke — they carry real added behavior (breakdown attributes + quarter-hour update on the price side,_get_ev()indirection on the EV side).
[0.1.51] - 2026-08-02¶
Fixed¶
onekommafive.refresh_nowacceptscoordinator: energy. The energy coordinator (added in v0.1.48 to backsensor.<sys>_daily_savings) was never registered in the service, so it could not be force-refreshed andallrefreshed only five of the six coordinators. Selector, schema, service handler and the DE user-facing description are all in sync now.
Changed¶
- Bump the
onekommafiveSDK pin to>=0.1.43,<0.2(from>=0.1.23,<0.2). Upstream0.1.24was a maintenance release (Auth0 login-state parsing hardened via regex, DRY refactors).0.1.25addedsystem.get_energy_savings(from_date, to_date)— aggregated Heartbeat savings (€) over a date range.0.1.30 → 0.1.43added a large batch of read-only endpoints:get_impact_overview(CO2),get_energy_trader(trading status + savings),get_heartbeat_ai_summary(resolution),get_monthly_trading_savings,get_price_customizations/get_comparison_price/get_price_guarantee(customer_id),get_wallboxes,get_smart_meter,get_site_details,get_self_sufficiency_events(start, end),get_customer(customer_id),get_notifications,get_notification_settings, plus new fields onHeartbeatAiSummary(peak-price-avoided) andSystemDetails(customer info). The new endpoints are not yet surfaced as Home Assistant entities. Every existing entity keeps itsunique_id,entity_idand translation key. - Internal refactor across
entity.pyandbinary_sensor.py:apply_stable_entity_idshelper now takes the platform domain string directly (call sites go fromf"{DOMAIN}.{{}}"toDOMAIN);OneKomma5DiagnosticSensorhangs off the generic_BaseSystemEntityinstead of duplicatingCoordinatorEntityboilerplate; the four near-clone binary sensors (Optimization Battery/HeatPump decision, EnergyTrader/DynamicPulse details flags) collapse into two spec-driven classes (OneKomma5OptimizationDecisionSensor,OneKomma5DetailsFlagSensor); shared plumbing of the today/tomorrow cheapest-window sensors extracted into_ChargingWindowBase. No unique_id or translation-key changes — existing entities keep their state, statistics and dashboards untouched. Net -66 lines across the two files.
[0.1.50] - 2026-07-28¶
Fixed¶
- Fresh-install entity_ids are now stable — every entity in the integration exposes
sensor.<system>_<code_suffix>/binary_sensor.<system>_<code_suffix>/ etc. on new installs regardless of Home Assistant's language and regardless of whether the entity is parented on the system parent or on a per-asset sub-device (inverter / heat_pump / meter / wallbox / vehicle). Before this fix HA composed sub-device entity_ids as<device_slug>_<entity_slug>from the translated device name, so a German fresh install landed onbinary_sensor.wechselrichter_verbundenwhile an English install landed onbinary_sensor.inverter_connected— the shippeddashboard/dashboard.yamlSYSTEM_NAMEplaceholder covered neither case. Achieved via a smallapply_stable_entity_idsshim called from each platform'sasync_setup_entry; existing entity_ids in the registry are preserved (HA registry looks up byunique_idfirst). Fixes issue #8.
Changed¶
dashboard/dashboard.yamlanddashboard/dashboard-showcase.yamlnow reference the stable English code suffixes (_pv_power,_heat_pumps_power,_electricity_cost,_feed_in_revenue,_diag_live_update,_cheap_electricity, …) instead of the previous DE-translated slugs. TheSYSTEM_NAMEplaceholder alone is enough for any HA language on a fresh install. Upgrading users whose registry still carries pre-fix DE-translated entity_ids should either rename their entities under Settings → Devices & Services → 1KOMMA5° → Entities, or sed the code suffix back to whatever their registry actually holds — seedashboard/README.mdfor the migration note.
[0.1.49] - 2026-07-19¶
Changed¶
- Pin the
onekommafiveSDK to>=0.1.23,<0.2. Home Assistant installs the requirement automatically on every install, so an upper bound stops a breaking SDK release from shipping untested to all users. Raise the cap deliberately when adopting a new SDK minor.
Fixed¶
- Hardening: every coordinator fetch is now wrapped in a 30 s timeout (
OneKomma5BaseCoordinator._fetch_timeout_seconds). Previously a hung SDK HTTP call could pin a coordinator (and an executor thread) indefinitely, sinceDataUpdateCoordinatorimposes no timeout of its own. A timeout now surfaces as a normal failed update — the entity goes unavailable and the next interval retries.
[0.1.48] - 2026-07-12¶
Added¶
sensor.<sys>_daily_savings— today's cloud-computed energy savings (€), read from the previously-unusedget_energy_today()endpoint (EnergyData.savings_eur). Daily running total that resets at local midnight (state_class=total,last_reset= start of local day), so Long-Term Statistics records one cycle per day. NewOneKomma5EnergyCoordinator(15-min interval) backs it, with a matchingdiag_energy_updatediagnostic timestamp. Currency follows the resolved account currency.sensor.<sys>_ev_battery_capacity— the vehicle's nominal battery capacity (kWh), from the EV profile'scapacity_wh.sensor.<sys>_ev_scheduled_departure_soc— the departure schedule's target SoC (%), distinct from the manualev_target_soc. Read-only.- Grid-cost breakdown attributes on
sensor.<sys>_current_electricity_price:spot_price,grid_costs,grid_cost_components,vat_rate,uses_fallback_grid_costs. Decomposes the all-in price as(spot + net grid costs) × (1 + vat)— components are net (ex-VAT); the SDK's VAT-inclusivegrid_costs_totalis intentionally not surfaced. - Translations for all new entities across all seven shipped locales.
[0.1.47] - 2026-07-05¶
Added¶
- Configurable duration on
sensor.<sys>_cheapest_charging_window_today— options-flow dropdown, 15-240 min in 15-min steps, default 60. Existing lock-in semantic preserved at the chosen duration. sensor.<sys>_cheapest_charging_window_tomorrow— twin of the today-sensor for tomorrow's forecast slots. Same duration option.unknownuntil tomorrow's prices arrive (~13:00 CET).onekommafive.refresh_nowservice — schemacoordinator: live | price | optimization | weather | system_status | all(defaultlive), optionalconfig_entry_id. Returns{"refreshed": [...], "failed": [...]}.- Bus events
onekommafive_negative_price_started/_endedon positive↔negative edges of the active 15-min slot. Payload:system_id,price,negative_price_slots_remaining. Granularity = coordinator refresh interval (1 h by default). - Three
SystemDetails-backed entities:binary_sensor.<sys>_energy_trader_active,binary_sensor.<sys>_dynamic_pulse_compatible,sensor.<sys>_system_age_days(diagnostic, unitd). - Three blueprints:
notify_negative_prices_tomorrow.yaml,notify_negative_price_started.yaml,ev_charge_on_pv_surplus.yaml. dashboard/dashboard-showcase.yaml— six-view showcase variant exercising the full integration surface. Originaldashboard.yamlstays as the compact layout.- Translations for all new entities and options-flow fields across all seven shipped locales.
Fixed¶
- Per-asset connectivity binaries no longer duplicate the asset noun ("Wechselrichter Wechselrichter verbunden" → "Wechselrichter Verbunden"). Translations on
inverter_connected/heat_pump_connected/meter_connected/wallbox_connectedreduced to the past-participle word in all seven locales.site_connectedunchanged.entity_id/unique_idunchanged.
[0.1.46] - 2026-06-28¶
Changed¶
- The EV (vehicle) sub-device now follows the same naming convention as the asset sub-devices shipped in v0.1.44: a translated label ("Elektrofahrzeug" / "Vehicle") as the device name, with
manufacturerandmodelcarrying the actual vehicle make ("Volkswagen") and model ("Id.5") from the EV profile. Before this version the device was named after the specific car withmanufacturer="1KOMMA5°"andmodel="EV Charger"— semantically wrong (the wallbox is the charger; 1KOMMA5° is the integration vendor, not the car maker) and inconsistent with the other sub-devices.entity_ids andunique_ids stay; long-term statistics, automations and Energy-Dashboard config are unaffected. Existing installs may need to disable + re-enable the integration once for the new naming to be picked up — a plain HA restart does not always re-merge the device registry. - New
device.vehicle.nametranslation key in all seven shipped locales (de/en/nl/es/da/sv/fi).
[0.1.45] - 2026-06-27¶
Added¶
- Multi-currency support — every monetary sensor (cost / per-consumer cost / feed-in revenue / electricity price) now picks its
unit_of_measurementfrom the site's country code. Correct unit out of the box in DK (DKK), SE (SEK) and AU (AUD); EUR continues to be the default for the four eurozone markets and unknown countries. Existing installs see no change to their unit. - Per-feature binary sensors — three new Booleans (
dynamic_tariff_active,time_of_use_active,smart_charging_active) reflect the cloud's customer-feature flags. Lets automations gate oncondition: state binary_sensor.X is oninstead of parsing theaktive_funktionenattribute list. The counter sensor stays for backward compatibility. - EMS-unavailable Repair Issue — when
get_ems_settings()fails for several refreshes in a row (most commonly: install has no DeviceGateway / no HEMS box), HA registers a Repair Issue in Settings → Repairs explaining the cause. Auto-resolves the moment EMS data returns. - System Health page — Settings → System → Repairs → System Information now surfaces per-coordinator status, API reachability, SDK version, resolved currency and country code. Useful as the "paste this into bug reports" panel; strictly PII-safe (no customer_id, no addresses, no system_id).
- Five new translation locales —
nl,es,da,sv,fi. Together with the existing German + English files, every 1KOMMA5° market is now covered (English doubles for Australia). Community native-speaker PRs welcome.
Changed¶
switch.<system>_ems_automatikmodusmoved toentity_category=DIAGNOSTICso it sits in the device card's collapsible diagnostic section instead of the main controls. The toggle appears to be cosmetic on the cloud side (the official 1KOMMA5° app doesn't expose it and the API write seems no-op), so it stops competing for attention with the controls that actually do something.entity_id,unique_idand existing automations referring to it stay untouched.sensor.<system>_letzte_optimierungsentscheidungis now an enum sensor with locale-aware state labels — e.g. "Batterie aus Netz laden" (DE) / "Charge battery from grid" (EN) instead of the raw SDK enum string. State values automations match on are lowercase (e.g.battery_charge_from_grid); update your automations if you previously matched on the uppercase form.- Entities for asset types that the cloud doesn't report on a given install (e.g. heat-pump entities on a setup without a heat pump) are now registered with
entity_registry_enabled_default=False. They still exist in the registry so adding hardware later preserves history; re-enable them manually under Settings → Devices & Services → 1KOMMA5° → Entities if you want them visible without an asset.
[0.1.44] - 2026-06-27¶
Changed¶
- The single
1k5device now splits into one parent device plus per-asset sub-devices (inverter, heat pump, meter, wallbox). Each sub-device carries its realmanufacturer,modelandfirmwarefrom the 1KOMMA5° cloud (PII-safe fields only). Long-term statistics, automations, dashboards and Energy-Dashboard config all keep working: entityunique_ids are unchanged, so existingentity_ids stay too. New installs will see sub-device names inentity_idslugs. - New diagnostic sensors
letztes_wetter_update/letztes_konnektivitäts_updatecover the previously un-tracked weather and connectivity coordinators (5 update timestamps total). - The system device now exposes
configuration_url = https://app.1komma5grad.com; HA shows a "Visit device" link to the 1KOMMA5° portal.
[0.1.43] - 2026-06-26¶
Fixed¶
weather.<system>(and theconditionshown by HA) reported the wrong sky state — typically stuck onclear-nightduring the day. The entity always returned the first forecast slot, which is the midnight UTC bucket because the API delivers slots ordered from the start of the current day. The active 3-hour bucket (period_start ≤ now) is now selected instead, socondition,native_temperatureandnative_wind_speedreflect the current slot.
[0.1.42] - 2026-06-25¶
Fixed¶
cheapest_charging_window_todayflickered to the next 15-min slot at every quarter-hour boundary — on flat-price days the state moved forward by 15 minutes every 15 minutes, which made it useless as an automation trigger. The sensor now locks in the chosen window: once selected, it stays as state until its end has passed (or the day rolls over). After expiry the next-cheapest window of the remaining day is locked in; once less than 60 min remain today, state isunknownuntil midnight.
Changed¶
cheapest_charging_window_todayis now restored across HA restarts viaRestoreSensor. A previously-chosen window survives a restart as long as its end is still in the future and its start is still today.
[0.1.41] - 2026-06-25¶
Added¶
- New sensor
cheapest_charging_window_today(timestamp + window attributes). State = start of the cheapest 60-minute window that still ends today (HA local time). Attributes:start,end,average_price,duration_minutes,slot_count. Re-evaluates at every quarter-hour boundary as the day shrinks. Drop straight into a "Charge at" automation trigger — noget_cheapest_windowservice call needed for the common case.
Changed¶
- README installation section simplified — integration is now in the HACS default store, so the custom-repository workflow is no longer documented.
- Internal refactor — pure cleanup, no user-visible change: collapsed boilerplate across
entity.py,coordinator.py,binary_sensor.pyand the diagnostic-sensor wiring (-121 LOC). Five identical entity bases now share one generic; four asset-connectivity binary sensors are one parameterised class; coordinators are configured via class vars instead of duplicated__init__calls.
[0.1.40] - 2026-06-04¶
Added¶
- New blueprint
notify_connectivity_lost.yaml— fires a notification when one of the v0.1.38 connectivity sensors (site, inverter, heat pump, meter, wallbox) stays OFF for a configurable debounce duration (default 5 min). Picker is filtered todevice_class=connectivityfrom this integration; default message templates the friendly entity name so a single blueprint serves all five sensors. - README Energy Dashboard setup section mapping every supported HA Energy Dashboard slot (grid import/export, solar, battery in/out, individual devices) to the friendly name + underlying translation_key, plus grid-pricing and feed-in-revenue sensor wiring.
Changed¶
- Reordered the top-level README so installation and configuration come before the entity reference. Old order had a ~300-line "Features" section ahead of the install instructions, which buried both setup steps and the dashboard/blueprint links. New order: Disclaimer → Installation → Configuration → Energy Dashboard setup → Example Dashboard → Blueprints → Entities → Services & Events → Requirements / Tech / Development / Credits. The "Features" H2 was renamed to "Entities", and the services + bus event were lifted to their own "Services & Events" H2. No content was removed or shortened.
- Bumped
onekommafivedependency to>=0.1.22. No new endpoints or fields consumed; the upstream release only adds an optional CLI token cache that this integration does not use. Pin reflects the current latest tested SDK version for clarity.
[0.1.39] - 2026-06-04¶
Changed¶
- Bundled the hDPI variant of the brand icon (
brand/icon@2x.png, 512×512 RGBA) next to the existingicon.png. Home Assistant's brands proxy (HA ≥ 2026.3) serves both via/api/brands/integration/onekommafive/, replacing the grey "Icon not available" placeholder in HACS' list and integration views. - README image references switched to absolute URLs so the corner logo and the License badge render correctly in HACS' README panel — the previous relative
<img src="custom_components/…">was stripped by HACS' HTML sanitiser, and the relative License link target broke the entire[![]()](…)element under the same sanitiser.
Removed¶
brand-prep/working directory.home-assistant/brandsno longer accepts PRs for custom integrations (2026-02-24 announcement); the directory was a staging area for that workflow and is now obsolete.
[0.1.38] - 2026-05-19¶
Added¶
- Site connectivity binary sensor (
site_connected,device_class=connectivity) reflecting whether the 1KOMMA5° cloud sees the system asCONNECTED. Pairs cleanly with HA's standard "device unavailable" notifications. - Per-asset-type connectivity binary sensors (
inverter_connected,heat_pump_connected,meter_connected,wallbox_connected, alldevice_class=connectivity). Each is registered only when an asset of that type is observed in the cloud's inventory — installs without e.g. a heat pump don't get a permanently unavailable sensor. AND-logic for multi-asset installs: a single disconnected device flips the sensor OFF. Attributes carry redacted per-asset detail (manufacturer / model / firmware / connection_status) — no serial numbers, no local IPs, no opaque IDs, no device names. - Active features diagnostic sensor (
active_features,entity_category=diagnostic) exposing the customer's enabled Heartbeat feature flags (DYNAMIC_TARIFF,TIME_OF_USE_OPTIMIZATION,SMART_CHARGING, …). State is the count; the full list lives in thefeaturesattribute. - Diagnostics download now includes a new
systemblock with redacteddetails(emp_type, dynamic_pulse_compatible, energy_trader_active, electricity_contract_active, earliest_measurement, …) andstatus_and_assets(site_status, asset_count, per-asset manufacturer/model/firmware/connection_status, active_features). Customer info, addresses, lat/lon, gateway gridx start codes, gateway/asset serial numbers, asset network IPs and asset opaque IDs/names are explicitly redacted.
Changed¶
- New
SystemStatusCoordinator(5-minute interval) drives the connectivity sensors. Combinessystem.get_status_and_assets()andsystem.get_active_features(customer_id)in one refresh; failure of the second call is silently swallowed (features fall back to[]) so a partial outage doesn't take the connectivity sensors offline. system.get_details()is fetched once at config-entry setup. Itscustomer_idis the only input required for the active-features endpoint; the rest is surfaced as redacted diagnostics. Failure is non-fatal:customer_id=Nonesimply means the active-features list stays empty.
[0.1.37] - 2026-05-18¶
Changed¶
- Bumped
onekommafivedependency to>=0.1.21. New release exposes three documented endpoints on theSystemclient (get_active_features,get_details,get_status_and_assets) that this integration does not yet consume — kept on the backlog for a future feature release.
[0.1.36] - 2026-05-16¶
Added¶
- AI: Heat pump recommendation binary sensor (
optimization_heat_pump_recommended) — ON when the Heartbeat AI's currently active HEATPUMP decision isHEATPUMP_RECOMMEND_ON. Symmetric to the existingoptimization_battery_grid_chargesensor; lets users automate the heat pump on AI-curated cheap slots without subscribing to the bus event. Off when the active HEATPUMP decision isHEATPUMP_AUTOor when no HEATPUMP event covers the current slot. - Diagnostics download — Home Assistant's standard
diagnosticsplatform is now wired up. Settings → Devices & Services → 1KOMMA5° → ⋮ → Download diagnostics produces a JSON dump useful for issue triage: redacted entry data (no username, password, system_id, unique_id), per-coordinator state snapshot (last_update_success, last_exception, update interval, summary of cached data), and the installedonekommafiveSDK version. Three Tier-2 tests guard the redaction contract and JSON-serialisability.
[0.1.35] - 2026-05-11¶
Added¶
- Per-consumer cost sensors — four new sensors (
Stromkosten Wärmepumpe,Stromkosten Wallbox,Stromkosten Haushalt,Stromkosten Klimaanlage) that allocate the grid-import cost proportionally to each consumer's share of total consumption (consumer_power / consumption_power × grid_consumption_power × stable_price). The four values sum to the existingelectricity_costsensor at every sample (invariant verified by a Tier-2 test). When PV/battery cover all consumption the grid bill is zero — all four sensors stop accumulating. Note: the API mocksacs_powereven for users without an AC unit, soStromkosten Klimaanlagemay be non-zero in those setups (same quirk as the existingacs_energysensor). - Automation blueprints — three ready-to-import blueprints in
blueprints/automation/onekommafive/: cheapest_window.yaml: schedule a switch /input_booleanfor the cheapest contiguous N-minute window in the price forecast (dishwasher, washing machine, EV manual run). Wraps theonekommafive.get_cheapest_windowservice.follow_cheap_electricity.yaml: mirror a switch's state tobinary_sensor.…_cheap_electricitywith optional time-of-day window — opportunistic loads like a hot-water booster or pool pump.notify_grid_charge.yaml: send a notification whenever the Heartbeat AI flipsbinary_sensor.…_optimization_battery_grid_chargeto ON.- Weather forecast — exposes
system.get_weather(). The integration adds aweatherentity backed by the location 1KOMMA5° already knows about, supporting the standard HA weather card and theweather.get_forecastsservice (hourly, ~48 h horizon in 3-hour buckets). Two extra sensorsSunshine today/Sunshine tomorrow(minutes) cover the PV-relevant data the WeatherEntity schema can't carry — useful for "only run the dishwasher if there's enough sun today" automations. New 1-hour weather coordinator; failures are non-fatal and retried on the next interval. CONTRIBUTING.mdcovering local setup (venv, pre-commit, pytest), PR workflow, scope, translation guidelines and release process. Linked from the README development section.- Tier-2 integration tests under
tests/integration/usingpytest-homeassistant-custom-component. New[test-integration]extras group inpyproject.toml; newintegration-testsCI job runs them on every push/PR alongside the existing helper tests. The Tier-1 helper suite stays the day-to-day fast feedback loop. Coverage so far (27 tests): - Config flow: single-system success, multi-system picker, invalid auth, cannot connect
- Reauth flow: success path, invalid credentials, system gone from account
- Reconfigure flow: success path, cannot-connect error
- Coordinators: EMS gateway missing falls back to
ems_settings=None; price and optimization first refresh failures do not block setup - Services:
get_cheapest_windowfinds minimum-average window,get_most_expensive_windowfinds maximum, "no integration configured" raises clear error, voluptuous rejects sub-15-minute durations - Optimization bus events: first refresh fires exactly one event for the latest decision; subsequent refreshes fire only events strictly newer than the last fired; idempotent on identical data
- Cost sensor: accumulates trapezoidally with positive prices, decreases with negative prices, stays at zero when no stable price is available
- Options flow: form pre-fills the current feed-in tariff, persists a new value, rejects values outside the [0.0, 0.5] range
- Stable price sensor: holds the last valid price across an empty API payload — guards the cost-sensor multiplier
- Charging-mode select: lowercase HA option
smart_chargeconverts correctly toChargingMode.SMART_CHARGEbefore the API call - Weather entity & sunshine sensors: the WeatherEntity reports the current 3-hour slot's mapped condition;
weather.get_forecastsreturns one entry per slot; the two sunshine sensors register with the expected per-day minute values .github/PULL_REQUEST_TEMPLATE.md— pre-fills new PRs with summary / type / how-tested / checklist sections..github/SECURITY.md— vulnerability-reporting policy via GitHub Security Advisories; clarifies in-scope vs upstream-HA / upstream-1KOMMA5° issues..github/CODE_OF_CONDUCT.md— adopts Contributor Covenant 2.1 by reference, with reporting channels matching the security policy.
Changed¶
- Dashboard example expanded with monthly bar charts (grid import/export and consumption-per-device), a 24 h power-flow line chart, and a Tag/Woche/Monat/Jahr time-range switcher for the cost & feed-in chart. Two new badges (
Günstiger Strom,Aktueller Strompreis) added to the Netz view header. - Dashboard now requires the
button-cardHACS custom card and aninput_select.stromkosten_zeitspannehelper (Täglich/Wöchentlich/Monatlich/Jährlich) for the new cost-time-range switcher. Both prerequisites are documented indashboard/README.md. - Dashboard screenshots optimised with
pngquant(~60 % smaller, no perceptible quality loss). dashboard/README.mdtranslated to fully English prose; literal config strings stay German on purpose.- Dashboard cost view now has a second
statistics-graphbelow the existing cost/feed-in chart that breaksStromkosteninto its four per-consumer slices (heat pump / wallbox / household / AC). Reuses the existing day/week/month/year switcher — no new helper needed.
[0.1.34] - 2026-05-08¶
Added¶
- AI: Battery grid charging binary sensor (
optimization_battery_grid_charge) — ON when the Heartbeat AI's currently active BATTERY decision isBATTERY_CHARGE_FROM_GRID. AI-curated alternative to the simple price-vs-daily-average heuristic ofcheap_electricity— fires when the HEMS has decided "now is the right grid-buy moment to bridge upcoming high-price periods", taking the full forecast and battery state into account. - New pure helper
active_optimization_event(events, asset, now)(with 6 unit tests) for finding the slot that is currently active for a given asset.
Changed¶
- Bumped
onekommafivedependency to>=0.1.20(internal refactor of authenticated HTTP calls; CLI cleanups; no public API change).
Tooling¶
- New CodeQL workflow (
.github/workflows/codeql.yml) — security and code-quality scan on push, PR, and weekly cron. - New lint job in
test.ymlrunning ruff viapre-commit/action. pre-commitconfig (.pre-commit-config.yaml) andruffsettings inpyproject.toml.- Repo-wide one-time ruff format pass;
datetime.timezone.utcmigrated todatetime.UTC. - Resolved CodeQL findings: unused module-level
_LOGGERs inservices.pyandswitch.pyremoved; the emptyexceptinOneKomma5StablePriceSensornow logs at debug instead of silently swallowing.
[0.1.33] - 2026-05-05¶
Added¶
- HA bus event
onekommafive_optimization_decisionis fired whenever a new optimization decision is observed. The event payload includessystem_id,asset,decision,from,to,market_price,market_price_currencyandstate_of_charge. The first refresh after a Home Assistant restart fires one event for the most recent decision (so the wiring is immediately verifiable); the day's earlier decisions are not replayed.
Tooling¶
- Debug log lines around the event-firing path so you can verify behaviour from the HA log without subscribing on the event bus first.
[0.1.32] - 2026-04-26¶
Added¶
- Re-authentication flow: when 1KOMMA5° credentials become invalid, HA automatically shows a "Re-authentication required" notification — enter new credentials in place without losing sensor history
- Reconfigure flow: proactive credential updates via Settings → Devices & Services → 1KOMMA5° → Reconfigure
- Service
onekommafive.get_cheapest_window: find the cheapest contiguous N-minute window in the price forecast — returns start/end timestamps and average price for use in automations (dishwasher, washing machine, EV, heat pump scheduling) - Service
onekommafive.get_most_expensive_window: find the most expensive contiguous N-minute window — useful for load shedding automations - Negative Price Slots Tomorrow sensor: count of 15-min slots tomorrow with negative price (available after ~13:00 CET)
- Cheapest Hour Now binary sensor: ON when the current 15-min slot is the cheapest in the next ~30h of forecast
Changed¶
- Bumped minimum Home Assistant version to 2024.10 (required for
_get_reauth_entry,_get_reconfigure_entry, anddata_updateshelper) - Cheap Electricity binary sensor: now updates dynamically every 15 minutes (was previously only updated on coordinator refresh)
- Refactor: pure helper functions extracted into
helpers.py(price slot lookup, forecast building, optimization aggregation, cheapest/most-expensive-window search, trapezoidal integration) - Refactor: introduced
OneKomma5AccumulatingSensorbase class shared by Energy / Cost / Feed-in Revenue sensors - Refactor: introduced
OneKomma5BaseCoordinator[T]generic base shared by Live / Price / Optimization coordinators - Refactor: introduced
QuarterHourUpdateMixinandsystem_device_infohelper to remove duplication across price sensors and binary sensors - Refactor: split
sensor.pyintosensor.py(setup + descriptions tuples),sensor_descriptions.py(dataclass descriptions) andsensor_entities.py(entity classes) - Refactor: consolidated reauth and reconfigure flows into a shared form handler
Fixed¶
- Optimization aggregation sensors (
optimization_total_cost,optimization_energy_bought,optimization_energy_sold) no longer declarestate_class: total. They are daily snapshots that reset at midnight, and recording them as totals without alast_resetwould feed Long-Term Statistics with a spurious midnight drop. Device classes (monetary / energy) are kept for unit formatting.
Tooling¶
- Added 37 unit tests covering all pure helpers + translation file consistency
- Added GitHub Actions workflow that runs the test suite on every push and pull request
- Added GitHub issue templates for bug reports and feature requests
- Switched build / test config to
pyproject.toml(replacespytest.iniandrequirements-test.txt)
[0.1.31] - 2026-04-26¶
Added¶
- Optimization sensors: 5 new sensors exposing Heartbeat AI optimization decisions (event count, cost/savings, energy bought/sold, last decision) — updated every 15 minutes
- Diagnostic sensors: 3 new timestamp sensors tracking the last successful API update for each coordinator (live, price, optimization) —
entity_category: diagnostic - Price statistics: negative price slots today, tomorrow's average/lowest/highest price
- Long-term statistics: all price sensors now use
state_class: measurement, enabling HA to record hourly min/max/mean automatically
Fixed¶
- Negative electricity prices are now handled correctly — the stable price sensor accepts negative values and the cost sensor reduces accumulated costs during negative price periods
- Price coordinator first refresh is no longer fatal — if the initial fetch fails (e.g. API rate limit), the integration starts normally
- EMS
DeviceGateway not founderror no longer blocks integration setup — EMS switch becomes unavailable while other sensors continue working
Changed¶
- Removed
device_class: monetaryfrom price sensors (incompatible withstate_class: measurementin HA) - Documentation: all entity names translated to English with translation key references
[0.1.26] - 2026-03-21¶
Changed¶
- Bumped
onekommafivedependency to>=0.1.15 - API library 0.1.15 adds a new endpoint for 1KOMMA5° optimizations (not yet used by this integration)
[0.1.25] - 2026-03-17¶
Changed¶
- Bumped
onekommafivedependency to>=0.1.14 - API library 0.1.14 updates the
/systemsendpoint to v4 (no breaking changes)
[0.1.24] - 2026-03-08¶
Fixed¶
- Options flow: replaced
NumberSelectorwith plainvoluptuousvalidation to fix 400 Bad Request error on HA versions < 2024.3
[0.1.23] - 2026-03-08¶
Added¶
- Electricity Cost sensor: accumulated grid import cost (dynamic price × kWh, integrates with HA Energy Dashboard)
- Feed-in Revenue sensor: accumulated feed-in revenue (configurable tariff)
- Cheap Electricity binary sensor: ON when current electricity price is below today's average
- Battery Charge Energy / Battery Discharge Energy sensors (split for HA Energy Dashboard)
- Options flow: feed-in tariff configurable via integration settings (default 0.0803 €/kWh)
- Dashboard: new "Prices and Costs" view with cost stats and monthly apexcharts chart
[0.1.22] - 2026-03-07¶
Removed¶
- README: removed stable electricity price section (superseded by dynamic price sensor)
[0.1.21] - 2026-03-07¶
Added¶
- Stable electricity price sensor with hold-last-valid logic (retains last known price on API gaps)
[0.1.20] - 2026-03-06¶
Changed¶
- Relaxed
onekommafivedependency to>=0.1.10(was pinned to exact version) - Switched to PyPI package
onekommafive(replaces direct GitHub dependency)
[0.1.19] - 2026-03-06¶
Changed¶
- README: restructured with disclaimer at top and credits at bottom
- README: added "vibe coded" note to disclaimer
- README: use
SYSTEM_NAMEplaceholder in automation example
[0.1.18] - 2026-03-06¶
Changed¶
- Dashboard: updated with apexcharts price chart and new screenshots
[0.1.17] - 2026-03-06¶
Changed¶
- Dashboard: updated EV view screenshot
[0.1.16] - 2026-03-05¶
Fixed¶
- Dashboard: replaced hardcoded heat pump sensor entity ID with
SYSTEM_NAMEplaceholder
[0.1.15] - 2026-03-05¶
Added¶
- README: EV SoC sync automation example (keep manual SoC entity in sync with actual vehicle SoC)
[0.1.14] - 2026-03-05¶
Changed¶
hacs.json: addedrender_readme: trueand minimum HA version2024.2- Dashboard: replaced hardcoded car entity prefix with
CAR_IDENTIFIERplaceholder
[0.1.13] - 2026-03-05¶
Added¶
- Dashboard README: template sensor code for
cheapest_future_hourandcheapest_future_price
[0.1.12] - 2026-03-05¶
Changed¶
- Dashboard: replaced hardcoded system entity prefix with
SYSTEM_NAMEplaceholder
[0.1.11] - 2026-03-05¶
Added¶
- Example dashboard with two views (grid/energy and EV charger controls), YAML and screenshots
[0.1.10] - 2026-03-05¶
Changed¶
- README: reorganised with a dedicated EV Charger section
[0.1.9] - 2026-03-05¶
Fixed¶
- EV departure time: use correct
primary_schedule_departure_time()getter and'HH:MM'string format
[0.1.8] - 2026-03-05¶
Added¶
- EV target SoC number entity (0–100 %, available in SMART_CHARGE mode)
- EV departure time time entity (primary schedule departure time)
[0.1.7] - 2026-03-02¶
Changed¶
- README: documented 15-minute slot accuracy for the current electricity price sensor
[0.1.6] - 2026-03-02¶
Fixed¶
- Current electricity price now reflects the active 15-minute slot (
start ≤ now) instead of rounding to the full hour
[0.1.5] - 2026-03-01¶
Changed¶
- Price forecast horizon extended from 24 h to 30 h
[0.1.4] - 2026-03-01¶
Added¶
cheapest_future_hourandcheapest_future_priceas attributes of the electricity price sensor
[0.1.3] - 2026-03-01¶
Added¶
- Energy sensors (kWh,
TOTAL_INCREASING) for all 8 unidirectional power sensors using trapezoidal integration
[0.1.2] - 2026-03-01¶
Added¶
- Sensor Grid Import Power (
grid_consumption_power): raw grid import power (always ≥ 0), in W - Sensor Grid Export Power (
grid_feed_in_power): raw grid export / feed-in power (always ≥ 0), in W - Requires
onekommafiveAPI library ≥ commit2283880
[0.1.1] - 2026-03-01¶
Fixed¶
- Brand icon: correct dimensions (256×256 px, RGBA) and transparent background
- HACS validation: sorted manifest keys, fixed brand asset path, pinned action version
- License badge replaced with static badge to avoid GitHub camo cache issue
Changed¶
- README: added early-beta / vibe-coded disclaimer
- README: added credits to BirknerAlex/hacs_1komma5grad
[0.1.0] - 2026-02-28¶
Added¶
- Initial release
- Live energy sensors: PV power, battery power & SoC, grid power, consumption, household, EV charger, heat pump, AC, self-sufficiency
- Dynamic electricity price sensors (15-minute resolution): current, average, lowest, highest
- Rolling 24-hour price forecast as
forecastattribute (Tibber/ENTSO-E compatible format) - EMS auto mode switch
- EV charging mode selector (SMART_CHARGE / QUICK_CHARGE / SOLAR_CHARGE)
- EV manual SoC number entity (SMART_CHARGE mode only)
- UI config flow with automatic system selection for multi-system accounts
- German and English translations