Skip to content

feat: add experimental local Deye ToU adapter and isolated preview - #5497

Closed
arturonaredo wants to merge 2 commits into
springfall2008:mainfrom
arturonaredo:feat/deye-local-inverter
Closed

arturonaredo wants to merge 2 commits into
springfall2008:mainfrom
arturonaredo:feat/deye-local-inverter

Conversation

@arturonaredo

Copy link
Copy Markdown

Summary

Adds an opt-in, experimental DEYE local Solarman profile, independently of
the existing SK and DeyeCloud profiles. Predbat remains the only planner and
inverter executor; no additional HA automation, cloud client or Modbus poller.

  • Explicit six-row ToU SOC / discharge-power / charging-source mappings.
  • Native charge/stop windows remain virtual instead of borrowing two physical
    row boundaries and leaving an inconsistent table.
  • Source-disable interlock before numeric changes; numeric HA-state match before
    enabling grid charge. Bounded retries, drift reconciliation and visible failure.
  • No writes to current limits, BMS, shutdown reserve, operating modes, ToU times,
    peak shaving, export policy or EV relays.
  • Physical adapter control defaults off. Charge hold is unavailable until
    explicitly commissioned per installation; no global SK freeze override.
  • Optional deye_shadow exercises the same translator against a private
    state copy alongside an unchanged existing controller. Its services cannot
    reach HA. Invalid real tables stay blocked; any sorted-table hypothesis is
    explicitly labelled and remains non-executing.

This PR does not include the import diagnostic (#5486) or joint-planning changes
(requirements: #5490). Those are separate workstreams and will be tested together
on a separate integration branch.

Validation completed locally

  • Full --quick suite with PREDBAT_KERNEL_REQUIRED=1: passed; four existing slow
    suites excluded by the standard quick selector.
  • 62 DEYE adapter cases, including failure/retry/invalid-input coverage. Tests use
    fresh fixtures, block network connections and stub only settling waits.
  • Real Execute.execute_plan through a real Inverter: demand, partial target,
    commissioned hold, target change, midnight-spanning window and return to demand.
    Exceptions are not swallowed; actual proposed service targets/values are checked.
  • 12 preview isolation checks, including a broken publication path: existing SK
    service-template calls remain identical; private observations/config are unchanged.
  • Every pre-existing inverter definition is structurally unchanged.
  • Pre-commit and MkDocs build passed. MkDocs retains three unrelated pre-existing
    missing-link/image warnings.
  • Privacy/diff review and GitNexus staged/compare analysis completed. The shared
    inverter registry gives a broad/critical graph radius; disabled-path regression
    tests and explicit unchanged-profile checks are therefore important.

Why draft / what is not proven

Solarman v26.01.31 can publish an optimistic HA state after a register write ACK.
The adapter calls this observed, never hardware-confirmed. Software tests do
not prove hold behaviour, firmware compatibility, electrical limits or topology.
Immediate control also retains its last physical table if Predbat/HA stops; it
does not provide an independent watchdog/rollback controller.

No physical commissioning result is claimed. An installation-level shadow trial
will be reported in a follow-up comment with its actual observed duration,
installed commit, failures and remaining activation gates. No private configs,
vehicle identifiers, credentials or raw household captures are attached.

@arturonaredo

Copy link
Copy Markdown
Author

Combined local shadow trial — initial evidence, not the final-duration report

The three independent draft PRs are #5486 (import diagnostics), #5497 (local DEYE)
and #5498 (joint planning). They are combined on
arturonaredo/batpred:test/three-pr-shadow-20261012.

  • Initial combined revision 7a800b7e67bcb60781740c16fe0efd89f20d1d82 installed at
    2026-10-12 00:32:55 UTC. Revision
    f9cdd87e4107df91f618adc1e8783c927b1f2de9 installed at 00:49:00 UTC.
    Both have GitHub-verified signatures. The latter includes feat: experimental native joint EV and home battery planning #5498's clock fix
    5653cc0e; it must not be credited with the earlier revision's runtime duration.
  • Only Predbat was restarted. Source/config hashes, protected automation/template
    files and configured ceilings were independently checked after installation.
    SK remains the real inverter profile and the existing single EV executor remains
    in control; both experimental outputs are non-executing. The unchanged bounded
    passive audit retains its original stop time.
  • Full quick suites passed on the two independent feature branches and their
    combination with the native kernel required. Four existing slow suites were
    excluded. Both golden debug cases passed on the combination. Post-clock-fix
    focused tests for all three features passed. Pre-commit passed; docs retain
    three unrelated pre-existing warnings. This is local evidence, not a claim
    that upstream CI has approved or passed these fork runs.

What the live trial has found so far:

  1. Fresh HA observations later than Predbat's rounded five-minute reference were
    incorrectly rejected as future-dated on startup. Fixed in feat: experimental native joint EV and home battery planning #5498, with a regression
    using a mid-slot startup and a separate rejection for genuinely future data.
  2. The existing six-row physical timetable is not sequential. DEYE correctly reports
    blocked; a separately labelled sorted-table hypothesis succeeds in memory.
    The real timetable was not modified and this is not a hardware-commissioning pass.
  3. The joint model currently reports no_plan_found for the observed configuration.
    This is a bounded-search/model result, not proof of physical infeasibility and
    not readiness to activate. Investigation continues.
  4. Existing native SK hold behaviour can command 0 A discharge. Verification
    distinguishes that temporary command from the preserved configured ceiling;
    no competing process forces the register back upward.

As of 00:55 UTC, this is roughly 22 minutes of combined-trial evidence,
not eight hours. The final comment will state actual observed duration per revision,
coverage gaps/stale readings, successes, failures and remaining activation gates.
No activation, outage/disconnection experiment, increased current limit or BMS
bypass is part of this trial. Private captures/configuration/vehicle identifiers
are retained locally and are not attached to the PRs.

Keep manual SOC floors and power ceilings, and replay proposed commands only against isolated states. Physical timetable repair and hold commissioning remain explicit hypotheses.
arturonaredo added a commit to arturonaredo/batpred that referenced this pull request Oct 12, 2026
Sources: PR springfall2008#5498 at 091716c and PR springfall2008#5497 at 68682c7. Conditional stale-SOC scenarios retain their freshness blocker. All controls remain shadow-only in the local rollout.
@arturonaredo

Copy link
Copy Markdown
Author

Shadow trial update — corrected planner and command replay installed

The integration branch now runs signed revision
2e62ea57e5a39943a96e37bd65f97b0867d8c4bb, installed 2026-10-12 03:37:59 UTC.
It combines #5486, #5497 at 68682c7a, and #5498 at 091716c8. Two subsequent
healthy native cycles and installed/protected-file hashes were verified.

Corrections supported by a real-data replay:

  • Reproduced 576 native battery-SOC points with 0.0 kWh difference before
    evaluating alternatives. The data snapshot was taken at 01:04 UTC, not now.
  • Added a limited battery-discharge action (fixed per-period battery power ceiling;
    EV remains full-rate), and reachability pruning for future manual SOC minima.
  • A bounded forecast-envelope retry produces a candidate passing native nominal
    and PV10 checks over 2880 minutes, with modelled peak import 5998.5 W.
  • All 576 candidate steps were translated through the real inverter entry
    point in memory: 804 simulated services, no real services. The table-repair
    and hold-commissioning assumptions remain explicitly labelled, not fulfilled.
  • Native prediction hot loop and kernel ABI are unchanged. These numbers are
    simulation evidence, not measured savings, physical confirmation or optimality proof.

Validation: the complete local test runner, with the native kernel required,
passed without the quick-suite exclusions (113.47 s). The four slow suites
also passed separately; both golden cases, pre-commit, docs and 33 isolated tests
of the installed HA executor passed. Upstream CI remains action_required;
these local results do not replace upstream approval.

Live findings and preserved boundaries:

  • Vehicle SOC stopped updating. Optional conditional_* scenarios retain the
    original timestamp/age and freshness blocker; they never represent an old
    value as a fresh measurement or authorise activation.
  • The real ToU timetable remains unchanged and blocked for activation.
  • Logbook reconciliation resolved the suspected short automatic restart: rapid
    ON events had direct authenticated-action context, not executor attribution.
    The attributed automatic restart waited 604.6 s. No guard was rewritten and
    no restart experiment was performed.
  • The original bounded audit remains untouched. Its old forecast check references
    retired external-planner entities, so that portion is unchecked; supplemental
    captures record the current native diagnostic and joint outputs.

SK and the existing EV executor still control the installation. There is no joint
apply route or automatic activation in this trial. The final comment will report
actual observation duration per revision, gaps, deadline evidence and remaining
implementation/commissioning blockers after the bounded window ends.

@arturonaredo

Copy link
Copy Markdown
Author

Adoption / migration tracking: #5501. This separate feature request records the proposed local Deye/Solarman scope, compatibility and commissioning gates, and the relationship to the existing SK ToU report #3895. It does not claim upstream approval or physical commissioning and is not an automatic closure of the earlier issue.

@arturonaredo

Copy link
Copy Markdown
Author

Observed PR source: 68682c7a793d46902b90bef981ff3d5feb6f41db.

Local DEYE remains independent from SK/Deye Cloud; HA read-back is only observed, never hardware confirmation. Adoption is tracked separately in #5501.

Final bounded shadow-observation checkpoint — not an activation approval

The scheduled eight-hour checkpoint closed at 2026-10-12 07:37:44 UTC.
It did not provide eight hours on any one installed revision. Three independent
PRs were combined only for this personal shadow installation; existing native
control and the sole Home Assistant EV executor retained physical authority.

Combined revision Installed at (UTC) Elapsed until replacement/checkpoint
7a800b7e67bc 2026-10-12T00:32:55.731601+00:00 0h 16m 4s
f9cdd87e4107 2026-10-12T00:49:00.191482+00:00 2h 48m 59s
2e62ea57e5a3 2026-10-12T03:37:59.309487+00:00 3h 59m 44s

Combined-installation elapsed time: 7h 4m 48s.
There were 94 passive five-minute HA-cache captures, from
2026-10-11T23:47:26.576775+00:00 to 2026-10-12T07:33:03.477804+00:00; earlier captures precede
the first combined installation. Collector errors: 0.
Captured native-error records: 0; captured gaps
over 420 seconds: 0. These are sample
results, not continuous health or electrical measurements.

Observed outcome and limits

  • Final read-only verification confirmed installed source hashes, protected
    automation/template hashes and configured limits unchanged. Grid ceiling 6000 W;
    domestic reserve/shutdown 10%/5%; charge/discharge ceilings 3000 W/8192 W
    (59 A/160 A). Temporary native current commands below those ceilings are valid.
  • Maximum grid value in the five-minute captures was
    5970 W. Recorder reconciliation additionally
    found a 6060 W observation at 00:30:43.896975 UTC, followed 0.825625 seconds
    later by the EV relay OFF attributed to the existing HA executor with the grid
    sensor as trigger. Its grid <= 6000 guard rejects that value. Shadow did not
    send that OFF. Coarse sampling therefore cannot establish absence of peaks.
  • The historical last_reported value is not reconstructible from ordinary
    recorder last_updated; no second freshness-guard failure is claimed. The
    source of the simultaneous total-load increase is also undetermined.
  • Recorded post-OFF domestic-SOC samples before departure were 18–21%, below
    the existing 25% restart gate. No forced restart or reduced reserve was used.
    Separate recorder/logbook reconciliation found an automatic OFF-to-ON interval
    of 604.616 seconds; faster examined ON events had direct authenticated-action
    context, not automatic-executor attribution.
  • At the exact 07:30 local departure checkpoint, EV SOC had no fresh reading:
    the last reported value was 53%, dated 00:30:09 UTC. 100% by departure was not
    demonstrated
    , nor is 53% claimed as a fresh departure measurement. The dated
    session then became departure_passed, with no proposed EV windows or next-day
    automatic renewal.
  • Joint states sampled: {"conditional_no_plan_found": 22, "departure_passed": 25, "invalid_input": 9, "no_plan_found": 12, "unsupported": 26}.
    Conditional calculations retained the stale-input blocker. The real ToU table
    remains unordered and hold/firmware/topology/capacity commissioning is unfinished.

Reproducible software checks

The installed combined source previously passed the complete local native-kernel
runner without exclusions, both golden replay cases and isolated installed-HA
executor checks (no physical switching). The real-data replay reproduced 576
native SOC points with zero error; a corrected offline candidate passed nominal
and PV10 over 2880 minutes. Command binding translated 576 steps through the real
DEYE inverter entry point against copied observations. These are software/model
checks, not measured target attainment or commissioned hardware behaviour.

All three published PR heads also passed a read-only GitHub Actions matrix on
the fork
: https://github.com/arturonaredo/batpred/actions/runs/38216980983. Each job checks its exact SHA, runs all pre-commit checks,
builds the kernel, runs quick tests (four slow suites skipped), and verifies the
original checked-in x86_64 binary, including 450 random parity configurations.
The harness cannot push commits and did not modify any PR branch.
This is head-SHA evidence, not the upstream merge-ref run or maintainer approval.

Maintainer request: please approve the pending upstream code-quality run
for this fork PR. My account lacks upstream write permission; no approval policy
has been bypassed or changed.

Decision

Not ready to activate. The observed installation is still off/shadow-only.
An explicit apply implementation is being developed separately and has neither
been installed nor observed in this window. Fresh EV/connection evidence, ordered
physical ToU configuration, hold and installation-specific commissioning, and
reviewed executable integration remain prerequisites. There was no automatic
activation. The independent original audit retains its separate stop at
2026-10-12 14:55:57.696791 UTC; its legacy forecast references do not establish
native forecast verification, and its outstanding incident/T6 work is not closed.

@arturonaredo

Copy link
Copy Markdown
Author

Superseded by #5505, rebuilt independently from upstream v9.3.8 following the shared-template direction in #5501. The replacement uses a maintained Deye/Solarman custom profile and opt-in generic observed service sequences, not a renamed brand-specific adapter. This branch and its evidence are retained; no deployment is part of the replacement. The separate joint-apply dependency remains explicitly out of scope for #5505.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant