Tariff transformation
The addition is applied after the VAT factor. Fixed rates use the same transformation, and a built-in tariff schedule applies it to its peak or off-peak rate. A source with a price floor (the RCE market price shortcut) first replaces the normalized price by max(price, floor), so the floor sits before the multiplier, VAT factor and addition. Include applicable variable charges once; do not apply VAT again to a source that already contains it. Fixed monthly charges are reporting metadata and do not affect dispatch or the extra-kWh calculation.
Net-billing deposit value
Under net billing the deposit pays only the energy part of what is owed to the seller, and after 12 months a month's refund is capped at ρ × that month's export value (30 % with hourly RCE, 20 % with RCEm). While the cap does not bind, full prices are exact. Once it binds, one more unit of export is worth only ρ / 1.23 of a sell price that contains the 1.23 coefficient (0.244 for 30 %, 0.163 for 20 %) and the energy part of an import costs nothing in cash. The optional deposit model (deposit_model: off by default, or the experimental manual) gives the optimizer two planning-only factors, export_value_factor and import_energy_factor, and needs the distribution part of the buy price (buy_distribution_rate and buy_distribution_off_peak_rate, with buy_distribution_mode included or added on top of a dynamic energy price) to know the deposit-payable energy part. The distribution rates take VAT only, not the multiplier or addition; added puts them on top of the buy price for the planner and the reported costs alike. off is the setting for every site, also one whose deposit is forfeited: measured on a one-year replay of 40 hourly-RCE homes, no factor lowered the yearly bill by more than 44 PLN and the factor at the cap raised it in all 40 (by 68–431 PLN with the annual formula, 21–306 PLN with the monthly ledger); with RCEm the factor changes the bill by less than 10 PLN; switching battery export off because of a forfeited deposit cost 154–662 PLN a year in all 16 homes measured. The auto model is withdrawn and a stored auto is read as off. Reported costs always stay at invoice prices, and with the model off the plan is unchanged. Details and the diagnostics in dispatch_policy.settlement: guide.
Negative prices remain valid in the generic integration. Clipping an export price to zero or applying a deposit valuation factor requires an explicitly prepared source or suitable configuration; neither is an automatic assumption for every RCE installation. The PL net-billing setup profile pre-fills the 1.23 deposit factor only together with a PSE preset or an RCE market price sell source (which floors at 0 itself); it never clips prices on its own.
First setup requires separate confirmation of the displayed buy source and household load source. Every preview and save validates current inputs and solves a bounded base plan. An infeasible or timed-out plan cannot be saved; extra-consumption guidance is calculated after saving. Existing installations retain their original final confirmation. The first-setup form also offers three optional setup-profile selectors, for settlement, a Polish buy tariff and inverter tuning.
Load forecast from history
The Plan and Forecast valid sensors expose load_quality: selected source, actual forecast method, per-segment history sample counts, and fallback coverage. fallback_fraction measures elapsed forecast time, including separate repeated daylight-saving hours. Recorder fallback raises load_history_fallback even when its estimated energy is zero. This detailed attribute is excluded from recorder history.
The history model averages complete hourly consumption samples by local hour and day group. With group_weekends enabled, weekdays share one group and weekends another; otherwise each weekday has its own group. Defaults use 14 days of history and at least two samples per bucket. forecast_half_life_days (default 0, off) weights each sample by 0.5^(age / half-life) so the profile follows a level change, such as the start of the heating season, within a few days; the result remains a mean. A synthetic backtest (benchmarks/load_forecast_backtest.py) with a half-life of 5 days cuts the morning error after a level step by about a third while keeping the evening error within 5 % of the plain mean; run it on your own recorder before enabling the option.
Each forecast slot receives its elapsed share of the matching hourly mean. Recorder statistics use reset-adjusted cumulative sums; power history is integrated over complete hours with coverage checks. Missing buckets use fallback_daily_kwh / 24 only when fallback is enabled. An explicit fixed daily estimate is also distributed uniformly at daily_load_kwh / 24 kWh per elapsed hour.
Timestamp identity and durations use UTC; day grouping uses the configured local timezone. Repeated daylight-saving hours remain distinct intervals.
Generic integration defaults and configurable limits
These are setup defaults in settings.py, not a statement about your saved options. The standalone engine helper has different default absolute thresholds; Home Assistant passes the configured values explicitly.
- Planning, display and reference horizons: 24 hours each; configurable from 1 to 48 hours. Display and reference horizons cannot exceed the requested planning horizon.
- Display interval: 60 minutes; options are 15, 30 or 60 minutes. At most 96 distinct probes are allowed across display and reference horizons.
- Extra-energy probe: 1 kWh; UI range 0.01–5 kWh.
- Flexible-load profiles: 3, 5, 10, 15 and 20 kWh; default power cap 3 kW and allowed block-price degradation 15%.
- BOOST ceiling: 0.01 currency/kWh. LIMIT floor: 1 currency/kWh. CHEAP/LIMIT percentiles: 25th/75th.
- Probe-failure policy:
absolute_fallback. Grid charging, battery export and curtailment: disabled.
- Default budgets: 10 seconds for the base plan, 2 seconds per probe and 60 seconds overall. Performance allows up to 30 seconds for each solve and 300 seconds overall. Probes share the remaining time after the base calculation and a one-second finishing reserve. A probe that does not finish within its limit is unknown, never approximated. With
self_sufficiency or backup_ready one probe takes several seconds already on the default 24-hour horizon with quarter-hour prices, so at the default limits their consumption levels are unknown for nearly every interval and the short_coverage policy applies with reason reference_probe_failed; on a 48-hour horizon this holds for every strategy. The guide lists the measured limits and what helps.
- Default periodic refresh: 15 minutes, configurable up to one hour. Significant source changes can trigger earlier recalculation; validity boundaries only validate sources and advance cached advice.
- Optional setup profiles may pre-fill some of these values once, for a new installation only; see setup profiles in the guide.
How calculation works
1. Build a baseline plan
The integration aligns source intervals without averaging away tariff boundaries, then solves a mixed-integer optimization using SciPy HiGHS. Each slot chooses import, export, battery charge, battery discharge, curtailed solar and end-of-slot battery energy.
All flow terms are kWh per native slot. Prices and wear use currency/kWh. Charge and discharge efficiencies, ηcharge and ηdischarge, are fractions between 0 and 1.
- Grid import and export cannot happen simultaneously within a slot; neither can battery charge and discharge.
- Power limits become slot-energy limits by multiplying kW by elapsed hours. The inverter bounds the magnitude of
PV − curtailment + discharge − charge; grid limits apply separately.
- With grid charging disabled, charging cannot exceed forecast solar surplus. With battery export disabled, discharge cannot exceed the forecast household deficit after PV.
- With curtailment disabled, its value is fixed at zero. Incompatible generation, load, battery and export constraints may then make a plan infeasible.
- The default
preserve_initial terminal rule requires final battery energy at least equal to initial energy. Its terminal credit is zero. In value mode, final energy is credited at terminal_value_per_kwh instead.
- An enabled daily cycle cap limits AC-side charge-plus-discharge throughput to
2 × capacity × daily_cycles per local date, less today's observed throughput. SOC efficiency is modeled separately; DC counters need upstream conversion. Zero disables the cap; a positive cap requires a current observed-throughput source.
The solver normally proves an optimum within its limit; if the limit runs out first, the best validated solution found so far is published with time_limited and its mip_gap. Returned flows are independently checked with a 0.000001 kWh absolute tolerance. These are AC-equivalent energy flows; equipment efficiency and usable capacity still need validation against measurements.
2. Add hypothetical consumption
For every display/reference interval, the integration adds a probe—normally 1 kWh—to forecast household demand. The added energy is spread uniformly in time across that interval and allocated to native slots by elapsed overlap.
It then reoptimizes the whole available planning horizon with prices, starting SOC, terminal rules and equipment limits unchanged. Extra consumption can cause more import, less export, different battery use or different future charging. The resulting cost includes those opportunity costs and any change in wear or terminal credit.
The interval starts at the snapshot time. With a 60-minute display interval, a snapshot at 21:35 covers 21:35–22:35. It can cross a tariff change at 22:00. It is not a price for consuming the entire extra kWh immediately.
A 1 kWh probe over 60 minutes adds an average 1 kW; over 15 minutes it adds 4 kW. Different probe sizes can produce different per-kWh costs when constraints bind. The last interval overlapping source coverage is clipped and probed at its actual duration without scaling down the configured energy. A very short tail therefore requires higher average power and can fail when equipment limits bind. That tail remains unknown while successful full reference intervals retain percentile guidance. Later intervals, infeasible probes and expired probe budgets remain unknown; they are not assigned a zero cost.
3. Compare with the reference horizon
Successful reference costs are sorted and configured percentiles are calculated by linear interpolation: for percentile p, position (n − 1) × p / 100 lies between two sorted costs. A failed source-clipped tail is excluded when at least one reference probe succeeded; a failed full interval invokes the configured policy. The minimum purchase tariff is taken independently from source slots overlapping the available reference range. Classification uses the rules in Consumption compass.
Reference coverage concerns the percentile horizon, not necessarily the entire planning horizon. If contiguous source coverage is shorter than the configured reference horizon, percentiles use that available coverage and the result reports it explicitly. Missing future prices do not by themselves invoke the probe-failure policy.
All 16 entities
Each installation creates 13 sensor definitions, two binary sensors and one strategy select, plus two sensors and one select when the optional Deye controller is enabled. Actual entity IDs depend on the entry name, language and registry history; use the entity picker or Developer tools → States to find yours. The keys below are stable internal identifiers, not literal entity IDs.
Expose costs controls the three cost sensors. Expose windows controls the four next_… sensors. A disabled entity is different from an enabled entity whose value is unavailable.
Consumption compass
consumption_compass · Kompas zużycia · Sensor
The level of the first consumption outlook interval. Let c be its extra-kWh cost, B the BOOST ceiling, L the LIMIT floor, Qlow/Qhigh the configured reference percentiles, and Pmin the minimum purchase tariff in the available reference horizon. Rules are evaluated in the order shown; the first match wins.
BOOST wins first, followed by CHEAP, LIMIT and NORMAL. Equality at the low percentile or minimum purchase tariff is CHEAP; a negligible numeric tolerance covers solver residue at those equalities. Equality at the BOOST ceiling is not BOOST, and equality at the LIMIT floor or high percentile does not trigger LIMIT.
With absolute_fallback, a failed full reference probe removes percentile tests but retains the independent minimum-tariff CHEAP rule. BOOST uses c < B; CHEAP uses c ≤ Pmin; LIMIT uses c > L; everything else known is NORMAL. With the unavailable policy, a full-interval failure suppresses levels. A failed source-clipped tail remains unknown without suppressing percentile advice from successful reference probes.
Unavailable: the baseline is invalid/expired, or the current guidance level is unknown. A low SOC is incorporated into the optimization; it does not independently force LIMIT.
Consumption cost
consumption_cost · Koszt zużycia · Currency/kWh
The finite-difference cost of the current display interval: (probe objective − baseline objective) / added kWh. Positive means extra modeled cost; zero means no change; negative means the extra load reduces the modeled objective. This is neither an electricity-meter reading nor the current buy rate.
Attributes include method: finite_difference and probe_kwh. Display rounding uses cost_precision; classification uses the unrounded value.
Unavailable: same gate as Consumption compass. Under the strict unavailable policy, this sensor is unavailable even if a numeric probe result survives in plan.outlook but its level is unknown.
Flexible energy depth
flexible_energy_depth · Głębokość elastycznego zużycia · kWh
Five independent counterfactual plans add 3, 5, 10, 15 and 20 kWh of flexible demand to the same baseline. Each profile can schedule at up to the configured power cap, 3 kW by default. The optimizer includes tariffs, PV, battery losses and wear, terminal value, grid limits and operating constraints.
The published state is the largest consecutive profile whose next block stays at or below the allowed price. The first degraded or unknown block stops depth; a later stable block cannot skip that gap. Negative anchors use the same absolute-difference rule, so −0.10 permits values through −0.085. A zero anchor permits no unfavorable positive increase.
Attributes expose the 3 kWh anchor price, allowed block price, configured power and degradation, currency, and all profile summaries. Profiles are grouped as small (3/5 kWh), medium (10/15 kWh) and large (20 kWh). Each includes total incremental cost, average and marginal block prices, import/export and battery-throughput deltas, status, failure reason and nonzero schedule rows.
This sensor measures price depth, not whether electricity is cheap in absolute terms. A stable depth can still carry an expensive anchor price. Compare anchor_price_per_kwh with the tariff or household policy before starting a load.
Unavailable: the baseline is invalid/expired, flexible-depth analysis is disabled, or the 3 kWh anchor cannot be solved within coverage, power and time limits.
Next change
next_change · Następna zmiana · Timestamp
The start of the first later outlook interval whose known consumption level differs from the first interval. Attribute next_level gives that level. It tracks consumption guidance, not an energy-state change or every tariff change.
The scan stops at the first later unknown level. If the current level itself is unknown, the entity implementation can return the immediately following known level; interpret this as the next known guidance, not a confirmed transition from a known current state.
Unavailable: no qualifying transition appears before the scan stops, or the baseline is invalid/expired.
Next boost start
next_boost_start · Początek zwiększonego zużycia · Timestamp
The start of the first active or upcoming contiguous BOOST window. Adjacent BOOST intervals merge. An active window can have a start timestamp in the past; it is not skipped in favor of tomorrow's window.
Unavailable: no BOOST window exists in the calculated outlook, or the baseline is invalid/expired. This does not assert that BOOST can never occur beyond forecast coverage.
Next cheap start
next_cheap_start · Początek taniego okresu · Timestamp
The start of the first active or upcoming contiguous CHEAP window. BOOST windows are separate; this entity does not mean “any favorable period.” The plan's favorable_windows combines adjacent BOOST and CHEAP intervals.
Unavailable: no CHEAP window exists, the baseline is invalid/expired, or the classification mode cannot produce CHEAP.
Next limit start
next_limit_start · Początek ograniczenia · Timestamp
The start of the first active or upcoming contiguous LIMIT window. It indicates an expensive additional-consumption period; it does not restrict inverter power or shut off household loads.
Unavailable: no LIMIT window exists in coverage, or the baseline is invalid/expired.
Attributes shared by the three window-start sensors
statusactive when now falls inside the window; otherwise upcoming.
end, duration_minutes, remaining_minutes- Window end, total duration and time remaining. Before an upcoming window starts, remaining minutes equals its full duration.
start_basisforecast for a predicted start; first_observed for an active window anchored when first observed. Overlapping active starts are preserved across recalculation and restart while the stored anchor remains applicable.
Home Assistant can omit dynamic attributes from unavailable entities. For absent windows, inspect plan.window_status: none_in_coverage, active or upcoming. Known later windows can remain available after a failed current probe.
Energy compass
energy_compass · Kompas energii · Sensor
One primary label for the first native plan interval. This interval can be shorter than the consumption display interval. Rules use interval kWh and a tolerance ε = 0.000001 kWh, in this exact precedence:
Pure solar self-consumption with an idle battery is HOLD, not SELF_CONSUME. Labels summarize proposed aggregate flows and do not confirm inverter mode, command execution or measured power.
Attributes contain the first interval's start, end, buy_per_kwh, sell_per_kwh, pv_kwh, load_kwh, grid_import_kwh, grid_export_kwh, charge_kwh, discharge_kwh, curtail_kwh and end_soc_kwh. The last value is stored energy, not a percentage.
Unavailable: the baseline is invalid/expired. A failed consumption probe alone does not hide a valid energy plan.
Plan
plan · Plan · Timestamp
The entity state is generated_at: the input snapshot time used to generate the plan, not solver completion time or planned end time. Detailed output lives in attributes.
Large forecast arrays are excluded from recorder history by the integration. Do not assume historical entity states retain the full plan arrays.
Unavailable: the baseline is invalid/expired. Expired previous plans are kept for diagnostics, not published as current advice.
Expected net cost
expected_net_cost · Przewidywany koszt netto · Currency
Calculated from the baseline over the display horizon, shortened to available coverage. A slot crossing the display end is counted proportionally. Attribute coverage_hours gives the actual duration.
Positive means modeled net spending; negative means export value exceeds import cost. “Net” means imports minus exports, not “excluding VAT.” Export value may represent a settlement credit rather than cash paid out.
This value excludes battery wear, terminal credit and fixed monthly charges. It is not automatically equal to the full optimizer objective or the final electricity bill.
Unavailable: the baseline is invalid/expired.
Expected wear cost
expected_wear_cost · Przewidywany koszt zużycia baterii · Currency
Uses the same display coverage and proportional boundary treatment as Expected net cost, with coverage_hours. Wear is a configured economic assumption, not a battery-health measurement or supplier fee.
At 0.05 PLN/kWh, charging 2 kWh and discharging 1.9 kWh costs 0.05 × (2 + 1.9) / 2 = 0.0975 PLN. A battery-free plan has zero wear.
Unavailable: the baseline is invalid/expired.
Optimizer status
optimizer_status · Stan optymalizatora · Diagnostic sensor
This entity remains available during calculation failures. Attribute expired_previous_generated_at identifies the last invalidated plan snapshot when one exists.
When the optional lifetime counters battery_charge_energy and battery_discharge_energy (battery round trip) or pv_energy (PV forecast accuracy) are bound as Sources measurements, attribute measured_calibration (also in the integration diagnostics) reports the measured round trip over 30 days next to eta_charge × eta_discharge and the real ÷ forecast PV ratio over 14 days, in total and per local hour. It is read-only and never changes a plan; without those sources the attribute is absent. See the guide.
Battery balance
battery_balance · Balansowanie baterii · Diagnostic sensor
Tracks the periodic LFP balance hold: a full-charge dwell that lets a lithium iron
phosphate pack's cells resettle voltage-wise. Disabled by default; enable it with the
LFP balance setting.
Attributes: last_completed, next_due, days_overdue,
planned_start, planned_end, planned_mode,
pv_series (median or pessimistic: the PV series that decided the
window candidates; see the optional pessimistic PV source), hold_progress_minutes, hold_required_minutes and
threshold_percent.
Unavailable: only before the balance tracker has loaded from storage.
SOC estimator
soc_estimator · Estymator SOC · Diagnostic sensor
The battery SOC computed from the lifetime charge and discharge energy counters when Battery SOC source
is Counter estimator (or while its Shadow run compares it with a bound SOC entity). Created only then;
turning it on or off reloads the entry. The state is a percentage and is recorded; of the attributes only
anchor_kind is recorded.
Attributes: energy_kwh, anchor_kind (initial, seed, full,
empty, reset), anchor_at, anchor_age_h, throughput_since_anchor_kwh,
pending_kwh, unanchored_top (the count reached the capacity without a full anchor, so the state is 99.9 %),
excess_kwh (the energy above the capacity, kept), full_candidate, measured_capacity_kwh,
eta_charge, capacity_kwh, mode (counter_estimator or shadow),
bms_soc (comparison only), full_candidates and anchors (the last 20 of each). See the
guide.
Unavailable: while the counters cannot be read.
Alert
alert · Alert · Diagnostic problem binary sensor
on: an input check or calculation failed. code identifies SOC jumps, invalid input, timeout, infeasibility or calculation errors; reason provides detail. since marks the first occurrence of the current problem, plan_retained identifies a covered previous plan, and last_successful_plan_at identifies its generation. A retry keeps the alert; successful publication clears it.
A corrected SOC can establish a new reference after fresh reports remain physically plausible for at least 60 seconds. Both the first and preceding recovery reports are checked. Missing/invalid readings or a new jump interrupt stabilization. Repeating the same timestamp is insufficient. The existing plan continues during this process.
Forecast valid
forecast_valid · Poprawna prognoza · Binary sensor
on: a valid baseline exists and current UTC time is strictly before valid_until. off: no published plan covers the current time. This entity remains available to report that condition.
Normally valid_until is bounded by periodic recalculation, forecast coverage and source freshness. During a refresh or failure, plan_retained=true keeps the last plan available until its actual coverage end; Alert reports input and calculation problems separately. Native interval boundaries advance current advice and commitment clocks without a new optimization. Fresh reports of unchanged inputs can extend freshness within those bounds; significant changes still request an earlier solve. An unchanged numeric SOC still needs a trustworthy report timestamp; availability is not established by its percentage alone. The default auto policy uses Home Assistant’s native last_reported for native SOC and BMS timestamp paths, including older saved last_updated paths. An identical fresh report therefore stays fresh. Custom timestamp paths retain their exact meaning; exact_path also preserves literal native-field selection.
current_guidance_valid- Whether the current consumption outlook has a known level. Use it together with the binary sensor's on state; it is generation metadata and is not itself a clock-based freshness check.
coverage_end, requested_end, coverage_complete- Actual source horizon, requested planning end, and whether that entire requested horizon is covered. These are distinct from reference-horizon classification.
input_ages- Snapshot ages in seconds based on Home Assistant
last_updated. Source-specific publication and SOC report timestamps can impose additional freshness checks.
missing_sources- Missing continuation identifiers or the invalidation reason, depending on whether a valid baseline exists.
Forecast valid does not certify tariff accuracy, battery capacity, perfect forecasts or physical execution. Those assumptions need separate validation.
Strategy
strategy · Strategia · Select
Strategies change planning weights and a few policy flags only; reported costs stay real currency. A new selection releases the carried operating-mode commitment for the next plan. The plan sensor reports strategy, autonomy_shortfall_kwh and cap_violation_kwh. Each strategy, its conditions and the automatic switch blueprint are described with diagrams in the states and strategies guide (wersja polska).
Deye controller
deye_controller · Sterownik Deye · Timestamp sensor, only with Options → Deye controller enabled
The state is the next instant the Deye controller must run: the earliest row end, the accepted plan's valid_until or coverage_end, or the next local TOU program boundary. Its attributes are the contract between Energy Compass and the executor (the native engine or the deprecated blueprint): controller_schema, mode, mode_entity, restore_pending, session, plan_reason (ok, session, revoked, sources), status, retained, generation, valid_until, coverage_end, accepted_at, revoked_generation, revoked_at, revoked_reason, the battery parameters capacity_kwh, eta_charge, eta_discharge, charge_kw and discharge_kw, device_id, program_prefix, tou_problem, next_tou, and the unrecorded accepted plan and tou values.
Unavailable: only while the entry is unloaded. The accepted plan is kept across an entry reload and dropped at a Home Assistant restart.
Deye mode
deye_mode · Tryb sterownika Deye · Select, only with the controller enabled
Off releases control after a confirmed restore of the base profile, Simulation computes every target without writing, Auto writes and verifies every register. The options are not translated. A fresh controller starts in Off.
Deye controller runtime
deye_runtime · Stan pracy sterownika Deye · Sensor, only with the controller enabled
The state is the runtime code (waiting, ok, blocked, restored, verification_required, write_failed, simulation_blocked, paused or error). The recorded attributes are restore_pending, reason, state, requested_mode, confirmed_mode, since, warning, takeover_blocked and accepted_generation; the full runtime and updated_at are not recorded. Detail-only changes are published at most once a minute.
Pause inverter writes
deye_pause · Wstrzymaj zapisy do falownika · Switch, only with the native Deye engine
While on, the controller computes and publishes the decision but sends no write. restore_pending and the uncertain registers stay as they are and the runtime code is paused. A run in flight stops before its next write; turning the switch off requests a run, and the usual rules decide between continuing and restoring the base profile. Mode Off with nothing to restore reports released even when paused; with a restore pending the pause wins. The flag is saved at once and is cleared when the engine is switched to blueprint.
Worked examples
These are explanatory scenarios, not live readings, recommended tariff settings or guaranteed savings. Their values illustrate the formulas above.
Battery capacity is not available energy
At 11% SOC, this 25 kWh battery has only about 0.244 kWh available to supply AC loads before the planning reserve, subject to power and other constraints. The optimizer cannot treat the nominal 25 kWh as immediately available.
Why NORMAL can coexist with a 1.25 PLN/kWh tariff
Use a deliberately simple battery-disabled, PV-disabled case to isolate the display-interval effect. Load is a fixed 24 kWh/day (1 kW), the grid import limit is 25 kW, export is zero, and no equipment limit binds. The snapshot is at 21:30; planning, display and reference horizons are 24 hours; probes are 1 kWh across 60-minute intervals.
Assume import costs 1.25 PLN/kWh from 06:00–22:00 and 0.61 PLN/kWh from 22:00–06:00, repeating daily. Export price and wear are zero; there is no battery terminal credit. BOOST ceiling is 0.01 and LIMIT floor is 1 PLN/kWh; reference percentiles are 25th/75th and all probes succeed.
The 24 reference costs contain seven full low-rate hours at 0.61, two mixed hours at 0.93, and fifteen full high-rate hours at 1.25. Thus Q25 = 0.61 and Q75 = 1.25. The current 0.93 is above BOOST, below the LIMIT floor, and not below Q25: NORMAL.
Baseline import cost is 8 × 0.61 + 16 × 1.25 = 24.88 PLN. The probe increases the objective to 25.81 PLN; the difference is 0.93 PLN. Energy compass is HOLD, Expected wear cost is 0, and Forecast valid is on while this generation remains fresh.
The first fully low-rate display interval begins at 22:30 in this snapshot's outlook, not at the 22:00 tariff boundary, because display bins are anchored to 21:30. Low-rate bins equal both Q25 and the minimum purchase tariff, so they are CHEAP. High-rate bins equal Q75 and remain NORMAL. The mixed current interval remains NORMAL, with the next CHEAP window beginning at 22:30.
Adding a nearly empty battery changes feasible flows and costs, but introduces no independent “low SOC means LIMIT” rule.
Solar consumption can have an export opportunity cost
In a separate one-hour example, disable the battery and assume 2 kWh PV, 1 kWh household demand, a 0.40 PLN/kWh export value, a 1.25 PLN/kWh import rate and nonbinding inverter/grid limits. The baseline exports 1 kWh, so its net objective is −0.40 PLN.
A 1 kWh extra-load probe consumes that surplus. Import remains zero, export falls to zero and the objective becomes 0 PLN:
No extra grid purchase occurred, but export value was lost. With a battery, the same comparison can also include changed charging, discharging, future purchases and wear. The integration recomputes the full plan instead of assuming every extra kWh costs the current buy rate.