feat(observation): separate physical load and unfiltered EV-SDL model without dispatch

This commit is contained in:
ENELIX Agent
2026-10-02 17:00:32 +00:00
parent 76f8b067cc
commit 44362e4bf5
9 changed files with 549 additions and 1 deletions
+88
View File
@@ -0,0 +1,88 @@
# Separate physical load / EV-SDL observation (NO dispatch or training permission)
## Implemented 2026-10-02
- `NetzfahrplanV4Messsicht` recalculates independent physical-load, physical-storage,
unfiltered modelled allocation and SolarEdge-origin views from explicitly identified
raw snapshots. Quality failures in held virtual accounts do not veto otherwise
consistent physical inputs. Missing/stale physical inputs still invalidate their
respective view. No automatic relaxation of age/skew limits.
- EV/SDL model: delta = physical - requestedEV - requestedSDL; distribute delta in
proportion to the absolute requested powers. The SDL component is obtained from
physical minus modelled EV to preserve numerical closure. This is an accounting
convention, NOT independently measured EV and SDL and NOT a verified response.
- Command changes more recent than the oldest physical feedback are flagged. Unknown
change timestamps, tracking mismatch, aged/missing origins and idle unallocated
power remain explicit. There is no held-value filter and no forced convergence of
displayed power to the requested value. All proposals keep `canDispatch=false`.
- Actual legacy filter outputs are displayed solely for comparison. They are not
reused as inputs of physical-load or unfiltered partition calculations. No changes
to the legacy filter, physical driver, EV/SDL setpoints, SOC integration or accounts.
## New read-only origin finding
Selected event 38921 writes legacy PV variable 20335 using:
a = 10 ** GetValue(41853) * GetValue(37975) + GetValue(21447)
if (a < 0) a = 0
SetValue(20335, a)
Arithmetic statements were inspected without exposing arbitrary scripts/credentials.
Verified saved configuration: variable 37975 parent 35514, register 40083; scale
41853 parent 48996, register 40084; battery 21447 parent 30789. An independently
updated 20335 is therefore not an independent PV reading and cannot certify all
input timestamps. A second constrained arithmetic read confirmed the condition
`if ($a < 0)`; this clamp applies to the legacy calculated PV value, not to the
new signed terminal-power observation. Neither proves the full AC/DC boundary.
The staged observer additionally records the ORIGINAL mantissa and exponent, not
only their periodically rewritten derived PV result. The alternative candidate
uses the scaled terminal power ONCE for this inverter (removing its derived-PV
and battery terms). GoodWe AC/DC boundaries and full-site physical boundary are
still unverified. This is not a definitive corrected house meter or live forecast.
## Standalone installation / operational scope
Stage on test host: `/srv/agent/netplan-v4-separated-observer-stage`.
User invocation inside Symcon only:
require '/srv/agent/netplan-v4-separated-observer-stage/install.php';
Creates only a NEW root category, three textual diagnostic variables, observe and
stop scripts and a NEW 30-second timer. Reads 23 existing numeric variables twice;
no Modbus polling requests, network calls, archive settings, existing module or
control timer updates. Existing 21-channel raw collector continues untouched.
New daily journals contain the selected numeric raw snapshot and derived views.
A new immutable mapping/inventory reference binds the corrected user EV allocation
161.44 kWh / 39 kW. Original collector metadata and its correction addendum remain
unchanged. No rescaling or resetting of virtual SOC/energy accounts.
Derived journal and LATEST/STATUS reports are 0644 WITHIN mode-0700 private stage
and data directories, allowing the authorized agent to inspect these selected
new outputs without repeated manual exports. No permissions on original journals,
Symcon directories or unrelated data are changed. Quotas reuse 64 MiB/day, 512 MiB
in total and 100 MiB disk reserve; exceeding them stops recording visibly and does
not delete old data. No network transfer or cloud trainer is activated.
## Validation and limitations
40 pure view checks + 32 native-mock checks passed on PHP 8.3 CLI at test host.
Regression: 36 raw-capture + 19 native-capture + 34 accounting checks passed with
new additive `raw_power`/`scale` units. Total 161 isolated checks. Full relevant PHP
source lint passed. Not a full PHPUnit run, Symcon kernel trial or hardware test.
Tests cover opposite EV/SDL requests, held output, non-unique partition labelling,
negative terminal power, scale/sentinel validity, old dependency timestamps, changed
commands, missing source, no duplicate native objects, unchanged existing signals,
append preservation, source drift, private output restrictions and stop behavior.
The observer is PREPARED, not started by the assistant. It does not replace the
installed receiver or its existing preview calculation. The preview/driver must
only be switched after measurement-boundary and feedback policy acceptance. Model
training and five-minute reconstruction must consume the new versioned snapshots
separately; there is no training eligibility or zero future-SDL assumption here.
Device-side command-loss protection and exact model/firmware identification remain
open. Official SolarEdge PDF fetch was unavailable (403/error); no device-specific
register suitability or watchdog behavior was inferred from a third-party source.