Skip to content

Add shared Deye/Solarman template with observed service sequences - #5505

Open
arturonaredo wants to merge 1 commit into
springfall2008:mainfrom
arturonaredo:feat/deye-solarman-template
Open

arturonaredo wants to merge 1 commit into
springfall2008:mainfrom
arturonaredo:feat/deye-solarman-template

Conversation

@arturonaredo

@arturonaredo arturonaredo commented Oct 12, 2026 •

Copy link
Copy Markdown

Status — 13 October 2026: Code from #5486, #5498 and #5505 is installed together at my home; household control is operating, but physical EV commissioning remains pending. See the consolidated report and use cases.

Current-main rebase update: all three PRs now include upstream main at 1faff2288982fd3cd159822c99c2658697c48f52 (v9.3.8 plus the five subsequent upstream commits). Heads: #5486 6db22f4e, #5498 fcf54648, #5505 4546443f. The publish_car_plan conflict is resolved: the joint EV publication guard remains before native publication, and upstream keeps a separate plan list for each car. This rebase was validated locally and did not deploy or change the home installation. The dated home observations below describe the earlier installed revision, not a deployment or physical EV commissioning of these rebased heads. The EV compatibility review is complete on the published trees: the existing joint guards are preserved. Compatibility limit: upstream CarChargerControl is not a joint-lease executor and must not be enabled alongside the sole external EV executor. This is a software/source review, not physical EV commissioning. The reproduced boundary and remaining limitations are described in the joint-planning report.

Current-head CI: run 38375561200 for 4546443f reports action_required and awaits maintainer approval; local tests are not an upstream CI pass.

Summary

Replaces #5497 following the shared-template direction agreed in #5501.

  • Rebased onto upstream main 1faff228 (including v9.3.8), independently of the diagnostics and joint-planning PRs.
  • Add a maintained templates/deye_solarman.yaml using the existing custom inverter_type / inverter: mechanism. No new built-in brand, component or adapter.
  • Add one opt-in generic service-sequence path: validate the complete list, observe each step in HA before advancing, stop on rejection/unobserved state, and retry from observed state on a later cycle. Compare final values before writing so a disable → target → enable sequence does not churn when already applied.
  • Keep legacy service execution and the configured/handled return contract. An explicit empty list handles an intentional no-op instead of invoking an opposite-direction fallback.
  • Document custom observed services and the local Deye/Solarman setup and limitations.

Supported scope and limits

The experimental template requests grid charging and ordinary self-consumption through all six ToU source/SOC rows. It does not program a six-period forecast into the inverter. Physical ToU times, Program Power, work mode, global currents, BMS and protection settings are not written.

It deliberately does not advertise forced export, freeze, hold, low-power/rate control, or a solar SOC ceiling. It ships with template: true; verified installation settings, single-writer ownership and site-specific failure/recovery commissioning are prerequisites before using Control charge.

HA read-back is an observation, not hardware confirmation. Group writes can partially apply; this is not an atomic transaction or a persistent-control watchdog. Stopping Predbat/HA does not undo ToU settings.

Initial development and validation did not change a live installation. Code from this PR is now installed at my home alongside #5486 and #5498, as reported above. Shared-template compatibility is implemented in #5498; planner-specific session/replay/execution gates remain owned there. This is not a claim of physical EV commissioning or a drop-in production recommendation.

Field evidence on one installation

There is now HA-observed grid-charge and demand operation on a SUN-16K-SG01LP1-EU: the retained 12 October charging receipt and recorder agree on all six rows at Grid / 59%; the 13 October 10:32 UTC read-only check finds all six at Disabled / 10%, native Demand and no reported error. The installed template/control implementation was matched to this PR; this is not a deployment of the complete rebased tree. See the consolidated report for anonymised telemetry, source provenance and reproducible checks. These observations are not independent hardware acknowledgement or general firmware certification.

Validation

  • Regression contracts reject the original upstream implementation (loaded in memory, without modifying the worktree).
  • Synthetic HA contract tests cover delayed and partial observations, rejection, exceptions, earlier-state reversion, whole-list preflight, zero values, reserve changes, multi-inverter fields and final-state idempotence.
  • The actual shared YAML is exercised through real native inverter construction, immediate controls, reset and execute_plan charge/demand/Monitor/read-only paths. No mock service writes target physical times, global currents, work mode or protections.
  • pre-commit run --all-files: all hooks pass.
  • MkDocs 1.6.1 build: passes; pre-existing unrelated documentation warnings remain.
  • PREDBAT_KERNEL_REQUIRED=1 python ../apps/predbat/unit_test.py: all 346/346 registered test groups pass on this exact rebased tree, including slow tests, native-kernel parity and golden debug cases. A fresh kernel was built and loaded; indexed source hashes were unchanged across the run.

@arturonaredo

arturonaredo commented Oct 13, 2026 •

Copy link
Copy Markdown
Author

Consolidated installation and integration update — 13 October 2026

Current-main rebase update: all three PRs now include upstream main at 1faff2288982fd3cd159822c99c2658697c48f52 (v9.3.8 plus the five subsequent upstream commits). Heads: #5486 6db22f4e, #5498 fcf54648, #5505 4546443f. The publish_car_plan conflict is resolved: the joint EV publication guard remains before native publication, and upstream keeps a separate plan list for each car. This rebase was validated locally and did not deploy or change the home installation. The dated home observations below describe the earlier installed revision, not a deployment or physical EV commissioning of these rebased heads. The EV compatibility review is complete on the published trees: the existing joint guards are preserved. Compatibility limit: upstream CarChargerControl is not a joint-lease executor and must not be enabled alongside the sole external EV executor. This is a software/source review, not physical EV commissioning. The reproduced boundary and remaining limitations are described in the joint-planning report.

Current-head CI: run 38375561200 for 4546443f reports action_required and awaits maintainer approval; local tests are not an upstream CI pass.

I have the code from #5486, #5498 and #5505 installed together at home, and the household battery planner is operating through Predbat's native control loop. This is no longer only a shadow display. The read-only check at 07:51 UTC found a normal 07:50 UTC Demand cycle, read-only off, no error, and the away car's relay and charging-slot signal off. Installed/protected file hashes and standing settings matched the deployment records.

This PR's role and use cases

This PR is rebased at 4546443f and owns only the reusable Deye/Solarman YAML template plus generic observed service sequences. It replaces #5497 in the direction discussed in #5501. The original no-live-change development statement described the initial validation stage; the later home installation is reported here.

  • Configure a local Deye/Solarman inverter through the existing custom-inverter mechanism and entity prefix, rather than adding another built-in brand or cloud controller.
  • Request ordinary self-consumption or grid charging through the six canonical ToU source/SOC rows, using the normal native entry points. This is not programming a six-period forecast into the inverter.
  • Preflight an entire service sequence, observe each step before proceeding, stop on rejection/unobserved state and retry from observed state. Final-state idempotence avoids unnecessary disable/target/enable churn. An explicit empty sequence remains an intentional no-op, not an opposite-direction fallback.
  • Compose with feat: experimental native joint EV and home battery planning #5498, now compatible with this template, for coupled fixed-rate EV/house-battery planning. Its latest head is fcf54648: unavailable-EV household fallback, bounded grid/PV sharing, continuous/ASAP charging preferences, explicitly authorised partial targets and durable session-validity checks. Add configurable whole-site import diagnostics (no enforcement) #5486 (6db22f4e) independently reports forecast import violations without enforcing them.

The template does not advertise forced export, hold/freeze, Program Power control, a solar SOC ceiling or variable EV power. It does not rewrite physical ToU times, work mode, global currents, BMS or protection settings. At home, local Solarman remains the inverter path; Deye Cloud stays disabled and the existing external EV executor remains the only automatic EV switch writer.

Concrete field evidence — charge and demand

The shared template is operating on my SUN-16K-SG01LP1-EU, through local Home Assistant/Solarman. There is now HA-observed evidence of both grid-charge and demand operation, not only a simulated plan. The software versions recorded at the 13 October check were Home Assistant 2026.10.1 and Solarman 26.01.31. This is evidence from one installation, not a model/firmware compatibility matrix.

Evidence, UTC Native status / control All six ToU rows, checked individually Reported telemetry
12 October, 23:01:31 — retained execution receipt, independently cross-checked against HA recorder Charging; read-only off Sources Grid; SOC targets 59%, matching the accepted native command Grid 3480 W, PV 0 W, house 420 W, battery −2870 W; battery SOC 30%
13 October, 10:32:37 — read-only inspection of the installed system Demand; Control charge mode; read-only off; no reported error; latest native cycle 10:30 UTC Sources Disabled; SOC targets 10% Grid 0 W, PV 1512 W, house 500 W, battery −913 W; battery SOC 15%

The recorder also shows battery SOC reaching 31% at 23:04:30 UTC during the earlier charging interval. Together with zero reported PV and negative battery power, this is consistent with grid charging. The power samples are the latest recorded values at or before the receipt, not simultaneous calibrated measurements; they are not an efficiency calculation or proof that the eventual SOC target was reached. The later demand sample is consistent with solar supplying the house and charging the battery without grid import.

Code/configuration provenance: the installed inverter file matches its deployment manifest, including the file retained during the earlier charge observation. Its generic service-sequence methods, routing wrapper and error class match public head 4546443f by AST comparison. All shared inverter-profile keys and the three service-sequence definitions match the public YAML after resolving the installation's entity prefix. The ten standing-control observations checked still match the deployment baseline. This does not mean the entire current-main-rebased tree was deployed: the observations are from the earlier installed combined revision, with the same template/control implementation.

Reproducible software checks on exact public head 4546443fdb9f9152213455743202e8fb795f0edb: the focused service_sequences, deye_solarman_template and execute groups were rerun on 13 October and all passed, without skips or source changes. The previously recorded full standalone suite passed 346/346 groups, with a freshly built/loaded native kernel. These remain local results; upstream CI awaits maintainer approval.

The template regression loads the actual shared YAML and exercises real native inverter/executor methods against synthetic HA: ordered disable → target → enable across all six rows, repeated-command idempotence, demand/manual minimum changes, failure before source enable, retry, reset, Monitor/read-only and absence of writes to unrelated settings. The generic sequence regressions additionally cover delayed/partial observations, rejection, exceptions and whole-list preflight.

With the repository test environment prepared and that head checked out:

cd coverage
./run_all --test service_sequences --test deye_solarman_template --test execute > template-tests.log 2>&1
grep -E 'PASSED|FAILED|ERROR' template-tests.log

Boundaries: this evidence supports the template's charge/demand path on this installation. HA read-back and recorded telemetry are observations, not independent physical acknowledgements or a general production certification. Hold/freeze, forced export, Program Power control, outage recovery, other firmware and physical EV charging are not established by these observations. No new hardware actions, configuration changes, restarts or faster polling were performed to collect this report. The EV relay/slot were off at the latest check; no session was authorised or renewed. Only this role-labelled summary is published, not private configuration, entity/device identifiers or raw captures.

Validation and remaining work

  • The exact rebased template head passed 346/346 registered groups, including slow tests and a freshly rebuilt/loaded native kernel. Its feature patch is unchanged (git range-diff).
  • The current-main-rebased planner head passed 364 registered groups independently; five optional-backend groups explicitly skipped real-template scenarios while testing safe rejection.
  • The rebased diagnostics head (6db22f4e) passed 345/345 groups.
  • The local combination of the three current public heads passed 367/367 registered groups, no skips, with the template required and a freshly rebuilt/loaded kernel. Pre-commit passed on both the planner and combined trees; documentation builds with existing unrelated warnings. No combined installation branch or private captures/configuration were published.
  • Installed household operation, protected hashes, preserved electrical/preferences settings and the unchanged OFF EV relay were checked. Offline deployment/recovery tests are not a live outage/recovery experiment. GitNexus impact/change analysis was rerun after reindexing. The full PR changes still carry critical risk and dynamic-call relationships remain unresolved; this is not a graph all-clear. Current-head upstream CI remains approval-blocked as reported above.

HA read-back is an observation, not hardware confirmation. Multi-row writes can partially apply; stopping Predbat/HA does not automatically undo persistent ToU settings. The shipped template remains guarded and installation-specific commissioning is still required.

No physical EV charging session is claimed. EV session authority remains disabled/expired and was not renewed. Charging, pause/restart, actual departure SOC, realised savings, outage recovery and instantaneous power enforcement remain unverified. The 160 A domestic limits, reserve/shutdown, 6000 W Peak Shaving, separate 16000 W EV cutoff and EV hysteresis/cooldown remain unchanged. No forced relay actions, faster hardware polling, BMS bypass or additional control writer were introduced.

@arturonaredo
arturonaredo force-pushed the feat/deye-solarman-template branch from 718476c to 4546443 Compare October 13, 2026 09:20

This branch has not been deployed

No deployments
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