mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2026-10-09 16:06:40 +00:00
feat: deliver complete GENETIC optimization to main (#1330)
* feat: adapt configuration for multi optimization algorithms Decouple configuration from optimization algorithm parameters. Add to_[algorithm]_param() methods to the configuration that derive optimization algorithm specific parameters from the configuration. Add x-scope tags to the configuration options that describe for which specific algorithms the configuration option is for. The whole device settings are restructured. There are now general settings for the device classes with the afore mentioned to_[algorithm]_param() methods. The general device settings got their own directory `devices/settings`. By this the parameter class also does not have to be a pydantic model which can be used for future optimization/ simulations speed up. Also the parameter class for a device is now part of the device module. This better decouples and also is the natural place for parameters of a device. Besides this feature there are also fixes and improvements: * feat: extend home appliance time window settings and simulation Home appliance can now be configured for multiple runs with per-cycle allowed time windows. The number of remaining cycles to plan is determined at runtime by reading the ``cycles_completed_measurement_key`` from the measurement store. * feat: specialiced CycleTimeWindowSequence for time window sequences Sequence of time windows associated to cycles. This model specializes ``ValueTimeWindowSequence`` so that the ``value`` field of each ``ValueTimeWindow`` encodes the **cycle index** (0-based integer) the window belongs to. Typical use: an appliance that must run ``n`` times per day, each run constrained to a distinct time window. Assign ``value=0`` to windows for the first cycle, ``value=1`` for the second, and so on. Multiple windows may share the same cycle index (their allowed regions are unioned). Windows with ``value=None`` are silently ignored by all cycle-aware methods. * fix: Make test_configmigrate also regard the _ANY_SENTENIEL in key values * chore: Make devices configurations a map instead of a list This makes config paths stable regardless of declaration order and lets each device settings class build its own config path from ``self.device_id`` without needing an external index. Tests are adapted likewise. Devices configurations are automatically migrated from lists to maps. * chore: rename levelized_cost_of_storage_kwh to levelized_cost_of_storage_amt kwh This better fits in the naming scheme and also makes clear the costs are money. Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com> * fix: runtime config update ignored by config file Runtime settings were handed back to pydantic-settings as init settings, which rank below the config file and the environment. Any key already present in EOS.config.json or in the environment silently discarded the update, so a bulk PUT /v1/config returned 200 without applying anything, while the granular PUT /v1/config/{path} endpoint kept working. Add a dedicated runtime settings source ranked directly below the command line arguments and record granular updates there as well, so both endpoints share one store that survives re-evaluation of the settings sources. Environment variables keep precedence over the config file for all keys that were not set at runtime. Also repairs revert_settings() and update(), which passed their data through the same init settings. Closes #1303 * fix: env vars ignored on first config build ConfigEOS.__init__ passed self as first positional argument to _setup, which forwards it to pydantic_settings.BaseSettings.__init__. Its first positional parameter is _case_sensitive, so the environment source matched the upper case variable names against the lower case field names and returned nothing. Environment settings only took effect after the next configuration setup. * docs: changelog for config priority fixes * fix(config): preserve device identities and storage costs during migration * fix(measurement): restore JSON records into the existing singleton * fix(devices): preserve charge-rate typing and public import compatibility * feat(measurement): integrate typed energy quality and capacity APIs Port the locally backed-up measurement extensions to main async storage and PR #1256 device maps. Preserve runtime capacity estimates across #1305 bulk updates. Confirm JSON singleton restore defect on unchanged main and add regression. No production configuration or measurements included. Co-authored-by: Andreas <drbacke@gmx.de> * docs(measurement): describe household settings and consolidate regression coverage * docs(measurement): regenerate configuration and API contracts * test(measurement): isolate capacity database state between tests * ruff format fix * fix(measurement): restore JSON records into the existing singleton * test(measurement): assert restored timestamps before timezone conversion * test(measurement): assert restored timestamps before timezone conversion * fix: preserve imported feed-in revenue during parameter preparation Cancel GENETIC preparation when imported revenue cannot be read or contains invalid values, preserving the chosen provider instead of replacing it with demo tariffs. Keep valid positive, zero and negative amount/Wh series unchanged. Adapt the revenue-preservation regressions from PRs #1224 and #1304 to the async main API, including real timestamped imports and simulation repricing. The feature-only direct-marketing override remains outside this main fix. Co-authored-by: Christin <info@bikinibottom.capital> Co-authored-by: Normann <github@koldrack.com> * feat(devices): port slot-aware battery export and direct-use physics Port scoped device changes fromd2e2d58237. Keep PR #1256 parameter conversion structure and separate GENETIC0 devices. Validate physical flows and reprice changed simulation results. Co-authored-by: Andreas <drbacke@gmx.de> Co-authored-by: Christin <info@bikinibottom.capital> * docs(measurement): align API version with refreshed prerequisites * fix: return only completed optimization results per run * feat(pvforecast): add calibrated local Akkudoktor backend Port local PV modeling and outage calibration from feature commitsf976335,6dc58c3andfaed0fdby Andreas. Keep PVForecastAkkudoktor identity and remote default, adapt to async storage, and migrate legacy provider settings. * fix(cache): distinguish callables in the shared EMS cache Include the function object in cache keys so methods of one interpolator cannot reuse a probability as a power value. Cover both call orders, keyword arguments, cache hits and separate closures with identical qualified names. * fix(devices): constrain the physics port and validate export levels Defer inactive EV deadline fields to the optimizer port, reject nonfinite export rates, and document the hourly Optimize boundary. Verify converter IDs, rates and LCOS, separate GENETIC0 interpolation, physical boundary flows and independent GENETIC repricing. * docs(pvforecast): regenerate local backend configuration schema * docs(devices): regenerate slot-physics configuration and OpenAPI schemas * test: type dynamic Optimize regression arguments * style: wrap imported tariff test parameter import * style(pvforecast): apply CI import formatting * docs(pvforecast): refresh API version after CI formatting * fix(config): satisfy typed device conversion and migration contracts * docs(config): refresh validated configuration prerequisite schemas * fix(measurement): enforce typed capacity and sample validation * test(devices): align physics regressions with strict type checking * style(measurement): normalize imports for CI * docs(measurement): refresh typed measurement API schemas * docs(devices): refresh API version after prerequisite merge * test: make optimization dispatch timezones explicit * docs(interpolator): use portable reStructuredText markup * docs(devices): refresh API version after docstring compatibility fix * feat: complete configuration-driven GENETIC optimization and reports (#1329) * feat(devices): port slot-aware battery export and direct-use physics Port scoped device changes fromd2e2d58237. Keep PR #1256 parameter conversion structure and separate GENETIC0 devices. Validate physical flows and reprice changed simulation results. Co-authored-by: Andreas <drbacke@gmx.de> Co-authored-by: Christin <info@bikinibottom.capital> * feat(optimization): port tested terminal and tail value primitives Sourced2e2d58237. 22 primitive tests pass; integration with the optimizer, forecast horizon and API is still pending. Co-authored-by: Andreas <drbacke@gmx.de> Co-authored-by: Christin <info@bikinibottom.capital> * fix(devices): preserve charge-rate typing and public import compatibility * feat(measurement): integrate typed energy quality and capacity APIs Port the locally backed-up measurement extensions to main async storage and PR #1256 device maps. Preserve runtime capacity estimates across #1305 bulk updates. Confirm JSON singleton restore defect on unchanged main and add regression. No production configuration or measurements included. Co-authored-by: Andreas <drbacke@gmx.de> * test(integration): validate optimizer economics and document measurement settings * docs(integration): record tested checkpoint and remaining consolidation work * docs(development): define isolated PR packages and remaining porting gates * docs(integration): refresh API version after measurement reconciliation * docs(integration): record PR readiness verification results * docs(development): record publication and verification of PR 1322 * test(measurement): assert restored timestamps before timezone conversion * docs(development): record corrected PR head and CI progress * docs(integration): refresh API version after prerequisite alignment * docs(integration): define parallel packages and Optimize compatibility gates * fix: preserve imported feed-in revenue during parameter preparation Cancel GENETIC preparation when imported revenue cannot be read or contains invalid values, preserving the chosen provider instead of replacing it with demo tariffs. Keep valid positive, zero and negative amount/Wh series unchanged. Adapt the revenue-preservation regressions from PRs #1224 and #1304 to the async main API, including real timestamped imports and simulation repricing. The feature-only direct-marketing override remains outside this main fix. Co-authored-by: Christin <info@bikinibottom.capital> Co-authored-by: Normann <github@koldrack.com> * test(integration): verify tariff protection with mapped device physics * fix: return only completed optimization results per run * test(integration): verify algorithm aliases and mapped-device contracts * fix(cache): distinguish callables in the shared EMS cache Include the function object in cache keys so methods of one interpolator cannot reuse a probability as a power value. Cover both call orders, keyword arguments, cache hits and separate closures with identical qualified names. * fix(devices): constrain the physics port and validate export levels Defer inactive EV deadline fields to the optimizer port, reject nonfinite export rates, and document the hourly Optimize boundary. Verify converter IDs, rates and LCOS, separate GENETIC0 interpolation, physical boundary flows and independent GENETIC repricing. * feat(pvforecast): add calibrated local Akkudoktor backend Port local PV modeling and outage calibration from feature commitsf976335,6dc58c3andfaed0fdby Andreas. Keep PVForecastAkkudoktor identity and remote default, adapt to async storage, and migrate legacy provider settings. * docs(integration): record combined compatibility checks and green JSON PR CI * test: type dynamic Optimize regression arguments * docs(integration): record Optimize fix PR publication * docs(integration): record imported tariff protection PR * style(pvforecast): apply CI import formatting * style(integration): align combined regression imports * test: make optimization dispatch timezones explicit * docs(interpolator): use portable reStructuredText markup * chore: validate combined integration with locked mypy * docs: hand off six validated pull requests for manual review * feat: report genetic interval and terminal value diagnostics * feat(devices): reconcile flexible profiles and EV deadlines with cycle scheduling Adapt the flexible consumer primitives fromd2e2d582while retaining the keyed settings and per-cycle scheduling introduced by #1256. Preserve slot battery physics and GENETIC0 flat-load conversion. Cover energy conservation, deadlines, window intersections, DST, completed cycles and EV converters. * test: satisfy typed genetic PDF chart contracts * feat(optimization): resolve quarter-hour GENETIC requests from configuration * test(genetic): verify real device scheduling, measurement and export contracts Register appliance completed-cycle measurement keys so the real store accepts both default and custom counters. Exercise complete low-budget optimizer runs, persisted measurements, generic solution output and instructions, including zero-power phases, EV departure boundaries, per-cycle windows and LCOS. * fix: bound genetic report forecasts to executable horizon * feat: complete native genetic scheduling and retained result contracts * fix: retain missing raw samples when dropna is disabled * fix: align local optimization slots and measurement instants * docs: explain complete genetic rollout and PR dependencies * feat: expose retained GENETIC report through the versioned API * docs: regenerate complete genetic configuration and API schema * docs: format consolidation and review handoff markdown * test: align isolated EMS fixture with native genetic run options * test(genetic): clean up singleton measurements after device integration tests * test: freeze the clock without replacing timestamp conversion * fix: preserve explicit warmstart timezones in runtime requests * test(genetic): validate device schedules in UTC and Berlin Use explicit Berlin origins for Berlin wall-clock windows, compare absolute deadline instants correctly, and run all real device optimizer scenarios under both UTC and Europe/Berlin. Compare exported starts in the run timezone instead of assuming the output timezone matches the host. * fix: start automatic genetic runs in the site timezone * Preserve aware GENETIC snapshot times across host timezones * docs: specify site clock and rehearsed merge resolutions * test: isolate invalid measurement records and refresh API version * fix: render single-slot genetic tail diagnostics * docs: refresh schema version after report fix * fix: preserve configuration-only Optimize API contract * docs: refresh configuration request schema --------- Co-authored-by: Christin <info@bikinibottom.capital> Co-authored-by: Normann <github@koldrack.com> --------- Signed-off-by: Bobby Noelte <b0661n0e17e@gmail.com> Co-authored-by: Bobby Noelte <b0661n0e17e@gmail.com> Co-authored-by: r0b2g1t <r0b2g1t@users.noreply.github.com> Co-authored-by: Normann <github@koldrack.com> Co-authored-by: Christin <info@bikinibottom.capital>
This commit is contained in:
co-authored by
Andreas
Christin
Normann
Bobby Noelte
r0b2g1t
parent
3c862543a1
commit
04f28997ea
@@ -0,0 +1,270 @@
|
||||
# EOS consolidation — integration record
|
||||
|
||||
Historical integration record, updated 2026-09-16. The completed optimizer port and
|
||||
current merge instructions are in [review handoff](review-handoff.md). Pending-work
|
||||
statements below describe earlier checkpoints.
|
||||
|
||||
Current PR-ready packages, dependency order and development guidance:
|
||||
[PR workflow](pr-workflow.md). The first independent fix is ready locally on main;
|
||||
the complete feature consolidation remains open.
|
||||
|
||||
## Pinned sources
|
||||
|
||||
- Official main: `4a3724424f98b5ce814d0340ddf3b6b5f1364752` (refreshed after initial checkpoint).
|
||||
- Feature branch: `d2e2d58237339454dd8bb226f92677c5987f8b27`.
|
||||
- PR #1256: `6ebd343047b87819b57778359784a616452b5f76`, open, conflicts.
|
||||
- PR #1305: `60b77f6da2da3a0f59518873fe7fbe9a92e733f4`, open, main target. Latest added commit is formatting only.
|
||||
- PR #1224: `0b12a34c11685822d97c3bc9f56c6292774cd930`, open, feature target.
|
||||
- PR #1304: `4b4b49f29902579a8deb34999d71eb2142c0620d`, open, feature target.
|
||||
- PR #1190 merged into main: GENETIC0 retained separately.
|
||||
|
||||
Sources: [issue #1192](https://github.com/Akkudoktor-EOS/EOS/issues/1192) and linked PRs.
|
||||
Issue body, all issue comments (none), and PR metadata were retrieved from the GitHub API.
|
||||
Use `refs/remotes/origin/main`: local `refs/heads/origin/main` is ambiguous.
|
||||
|
||||
## Isolation and recovery
|
||||
|
||||
Original EOS worktree remains on the feature branch. No reset, stash or checkout there.
|
||||
Integration branch: `integration/eos-consolidation-20260916`, sibling directory
|
||||
`EOS-integration-20260916`. Unmodified main comparison worktree: `EOS-reference-20260916`.
|
||||
|
||||
Private backup: `%USERPROFILE%/.codex/backups/eos-20260916-120324`.
|
||||
102 modified/untracked files copied byte-for-byte with SHA256 verification; binary
|
||||
tracked and index patches, original status/refs, verified `repository.bundle`.
|
||||
See private `RESTORE.md` and `manifest.json` for recovery into a NEW checkout.
|
||||
Ignored runtime files stay in the original worktree; this is not an archive of its
|
||||
virtual environment, caches or ignored production datasets. Backup is private and
|
||||
may include credentials or real measurements; never stage or publish it.
|
||||
Only explicitly reviewed source/test/document paths are staged for new commits.
|
||||
|
||||
## Functional matrix
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
| Area | Evidence | Integration state |
|
||||
| --- | --- | --- |
|
||||
| Providers, SMARD, fee model | #1192 checked; main prediction modules and #1235 | Keep main implementation; provider equivalence not yet established |
|
||||
| GENETIC0 / legacy API | #1190; `core/ems.py`, `server/eos.py`, `optimization/genetic0` | Preserved; device regressions pass, full endpoint validation pending |
|
||||
| Device maps / algorithm conversion | #1256; `devices/settings`, `config/configmigrate.py` | Merged with original history; four merge conflicts resolved |
|
||||
| Runtime updates | #1305; `config/config.py`, `core/pydantic.py` | Merged with original history; configuration tests pass |
|
||||
| Stable IDs / LCOS migration | New `test_consolidation_config.py` | Four initial regression failures fixed; 55 configuration tests pass |
|
||||
| 15-minute battery/inverter physics | Feature `devices/genetic`, `prediction/interpolator.py` | Ported in c0796e1; parameter classes retained in device modules, export/slot/efficiency tests pass |
|
||||
| New GENETIC, adaptive evolution, export states | Feature `optimization/genetic/genetic.py` | Pending; current optimizer is not the complete feature optimizer |
|
||||
| Warm start alignment | Feature d2e2d58, `test_genetic_warm_start_alignment.py` | Pending |
|
||||
| Control horizon / forecast tail / terminal value | Feature a2f4ef6, `tailvalue.py`, `terminalvalue.py` | Primitives ported in f70a786; 22 tests pass. Optimizer/horizon/API integration pending |
|
||||
| EV deadlines / flexible consumers | Feature f24d9ea; #1256 cycle windows | Pending reconciliation: preserve both per-cycle windows and profile/deadline semantics |
|
||||
| Imported feed-in revenue | #1224 + #1304, 38 feature regression cases | Neither PR targets main; adapt after GENETIC preparation port, keep author credit |
|
||||
| Local calibrated PV | Feature f976335/6dc58c3/faed0fd | Pending; keep public provider ID PVForecastAkkudoktor per #1192 |
|
||||
| Algorithm-specific PDF | Main #1205 vs feature utils/visualize.py | Keep on-demand API; feature slot/tail fields pending |
|
||||
| Measurement channels/energy/quality/capacity/household | Original uncommitted source + five new tests | Ported in 7338baf to async storage and keyed devices; 127 related tests passed |
|
||||
| Request configuration learning | Original uncommitted `genetic/configrequest.py` | Secured only; pending |
|
||||
| HA-private core differences | Separate private repo | Not ported; no HA files modified, no deployment |
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
## Completed packages and tests
|
||||
|
||||
1. `d3f96c4`: merge #1256 onto pinned main. Conflicts in devices.py and three generated
|
||||
documents; preserve maps/settings and main evolution. Regenerate OpenAPI from
|
||||
merged code. Do not adopt PR build version bumps. 244 configuration/time-window
|
||||
tests + 81 device/simulation tests passed before subsequent packages.
|
||||
2. `b43c8df`: merge #1305 without conflicts. 275 config/configabc/configmigrate/pydantic
|
||||
tests passed.
|
||||
3. `e3987b2`: stable map identities, reject key/ID mismatch, preserve renamed LCOS,
|
||||
repair legacy EV charge-rate migration. 4 regression cases failed before fix;
|
||||
55 related tests passed afterwards. These are integration/PR defects, not claimed
|
||||
as unchanged-main defects.
|
||||
|
||||
Tests currently use the existing Python 3.11.9 environment read-only; pytest adds
|
||||
this worktree's src. No mutation of the original venv. Missing pypdf 6.19.0 installed into the private
|
||||
backup test-packages directory and exposed only through test-process PYTHONPATH.
|
||||
This is not yet validation against every pinned dependency / CI Python version.
|
||||
Synthetic pytest fixtures; no real devices, server deployment or production config.
|
||||
|
||||
## HA handoff and acceptance
|
||||
|
||||
Do not relocate active feature development to this integration branch yet.
|
||||
Device collections are keyed maps, with identical map key and device_id. New settings
|
||||
live in devices/settings; conversion methods derive algorithm parameters. LCOS
|
||||
configuration is `levelized_cost_of_storage_amt_kwh`; old files migrate.
|
||||
Runtime config bulk/granular precedence follows #1305. Both algorithms remain
|
||||
separate; `/optimize` uses GENETIC0 and cannot demonstrate the new GENETIC port.
|
||||
Pin a final tested commit for HA only after all remaining packages and end-to-end
|
||||
API/forecast/output tests. No public push, PR, comment or main update is authorized.
|
||||
|
||||
1. `c0796e1`: slot-duration-aware battery/inverter simulation, bounded per-slot
|
||||
discharge/export, probabilistic direct-use energy model and GENETIC converter
|
||||
support for LCOS/export levels. Original author co-authorship retained.
|
||||
Fixed monetary goldens from the previous model are intentionally replaced with
|
||||
independent grid-flow repricing. Original simulation test passed on unchanged
|
||||
main; the changed result is not labelled a baseline failure.
|
||||
2. `f70a786`: bounded forecast reader, concave terminal value and deterministic
|
||||
forecast-tail primitives. 22 direct primitive tests passed. Does NOT activate
|
||||
the new optimization algorithm, warmstart, horizon handling or diagnostic API.
|
||||
3. `d9c434f`: keep main's charge-rate ndarray contract and exported constant after
|
||||
`#1256`. The first broad collection found this missed overlap.
|
||||
4. `7338baf`: typed measurement channels, sample quality, energy integration,
|
||||
household accounting and battery capacity estimation. Adapt all storage calls
|
||||
and endpoints to main's async API; map battery IDs through device collections.
|
||||
Capacity estimates survive subsequent runtime config updates and never change
|
||||
the active capacity_wh. 127 new/existing measurement tests passed, including
|
||||
JSON/SQLite/LMDB restart, partial coverage and real FastAPI routes with no lifespan.
|
||||
JSON measurement reload regression reproduced on unchanged afb7bcb (0 records
|
||||
after reload); applying the previously local singleton fix resolves it.
|
||||
5. `876756b`: replace stochastic GENETIC output equality with schema, independent
|
||||
per-slot cost/revenue accounting and physical-range assertions. GENETIC0 goldens
|
||||
remain unchanged. Short optimizer/PDF runs: 4 GENETIC0 and 4 GENETIC pass; one
|
||||
400-generation case for each algorithm skipped by the existing --finalize rule.
|
||||
New household configuration field has documentation metadata.
|
||||
|
||||
### Remaining integration risks and concrete next package
|
||||
|
||||
The current GENETIC orchestration is still the main-era optimizer with the newly
|
||||
ported device physics. It must NOT be described as the complete feature optimizer.
|
||||
Next port `optimization/genetic/genetic.py`, its parameter preparation and solution
|
||||
model together, carrying feature d2e2d58 warmstart and #1304 revenue fixes. Translate
|
||||
old top-level optimization settings to `optimization.genetic`. Check the actual
|
||||
prediction record units: current `elecprice_marketprice_wh` and `feed_in_tariff_wh`
|
||||
arrays already contain amount/Wh; only amount/kWh configuration is divided by 1000.
|
||||
Do not apply a second conversion to the existing *_wh arrays. Use #1256 `to_genetic_*` converters
|
||||
instead of reintroducing parallel settings. Reconcile flexible profiles/deadlines
|
||||
with #1256 per-cycle windows/completed cycles before exposing the combined API.
|
||||
Both porting sides must retain their regression cases. Follow with local PV and
|
||||
algorithm-specific on-demand PDF; do not copy feature's synchronous/automatic-PDF
|
||||
server paths over main. Then adapt local configrequest.py to the current API.
|
||||
|
||||
No feature-provider robustness fixes are claimed ported merely because a provider
|
||||
with the same name exists on main. HA private-core differences remain unaudited.
|
||||
No full 2030-test suite run, --finalize optimization run, dependency-pin CI matrix,
|
||||
or physical installation validation has been completed.
|
||||
|
||||
### Backup verification
|
||||
|
||||
An independent clone of repository.bundle at the original feature HEAD was restored
|
||||
using the backup files. All 102 restored SHA256 hashes match. The original worktree
|
||||
HEAD and all 102 file hashes were also rechecked unchanged after the source ports.
|
||||
|
||||
## Reproducing the focused acceptance run
|
||||
|
||||
Use a disposable environment with the repository dependencies plus pytest,
|
||||
pytest-asyncio, pytest-xprocess, pytest-cov and pypdf. The private backup contains
|
||||
`test-environment.json`, `integration-final.xml` and the complete collection log.
|
||||
Run from the integration worktree (not the original feature worktree):
|
||||
|
||||
```powershell
|
||||
python -m pytest `
|
||||
tests/test_typingmodels.py `
|
||||
tests/test_config.py `
|
||||
tests/test_configabc.py `
|
||||
tests/test_configmigrate.py `
|
||||
tests/test_configfile.py `
|
||||
tests/test_pydantic.py `
|
||||
tests/test_consolidation_config.py `
|
||||
tests/test_genetichomeappliance.py `
|
||||
tests/test_genetic0battery.py `
|
||||
tests/test_genetic0inverterefficiency.py `
|
||||
tests/test_genetic0simulation.py `
|
||||
tests/test_battery.py `
|
||||
tests/test_inverter.py `
|
||||
tests/test_inverter_efficiency.py `
|
||||
tests/test_geneticsimulation.py `
|
||||
tests/test_geneticsimulation2.py `
|
||||
tests/test_terminalvalue.py `
|
||||
tests/test_tailvalue_physics.py `
|
||||
tests/test_interpolator.py `
|
||||
tests/test_measurement_channels.py `
|
||||
tests/test_measurement_energy.py `
|
||||
tests/test_measurement_household.py `
|
||||
tests/test_battery_capacity.py `
|
||||
tests/test_measurement_file_restore.py `
|
||||
tests/test_measurement.py `
|
||||
tests/test_genetic0optimize.py `
|
||||
tests/test_geneticoptimize.py `
|
||||
tests/test_doc.py `
|
||||
-q `
|
||||
--tb=short
|
||||
```
|
||||
|
||||
Do not inherit EOS_DIR/EOS_CONFIG_DIR from documentation generation when running
|
||||
pytest: these conflict with fixture-controlled temporary config directories.
|
||||
Generate OpenAPI after committing source changes; source-dirty version timestamps
|
||||
otherwise make exact documentation comparisons nondeterministic.
|
||||
|
||||
## Final verified checkpoint for this work session
|
||||
|
||||
Focused combined run: **633 passed, 2 skipped in 65.46 s**. The skips are the
|
||||
existing 400-generation --finalize cases. Zero remaining failures in that run.
|
||||
All 2030 collected tests were collectable after supplying pypdf and resolving the
|
||||
charge-rate import overlap; collection alone is not a pass of the full suite.
|
||||
Ruff passed for the ported measurement/device/interpolator/primitive source files;
|
||||
git diff --check passed. OpenAPI/config documentation generation and the documentation
|
||||
comparison tests passed. The first combined run caught fixture state leakage in the
|
||||
new battery test; reset-before/after fixture isolation resolved it on the repeated run.
|
||||
|
||||
This is a tested partial integration checkpoint, NOT completion of the consolidation.
|
||||
The source packages are locally committed; release, full feature acceptance and
|
||||
upstream submission remain pending. Do not move active development or HA deployment
|
||||
here until the remaining optimizer/prognosis/output/request packages are integrated.
|
||||
|
||||
## PR-readiness verification, 2026-09-16
|
||||
|
||||
Current main `7ebe6d7` is incorporated. Two reviewable local packages now exist:
|
||||
`fix/measurement-json-reload` (`dba0c9c`, independently based on main) and
|
||||
`feat/measurement-energy-quality-capacity` (`ea3383e`, depends on the configuration
|
||||
integration base `d546f08`). The latter excludes the new optimizer/device physics.
|
||||
See [PR workflow](pr-workflow.md) and its concrete draft descriptions.
|
||||
|
||||
The expanded integration run completed with 764 passed, 3 skipped and 2 documentation
|
||||
failures in 453.99 seconds. Both failures were solely stale generated OpenAPI version
|
||||
metadata, not schema or functional differences. Regenerated the two files; the focused
|
||||
rerun of all 5 documentation tests passed. No remaining failure from that selection.
|
||||
The complete expanded selection was not rerun after this documentation-only correction.
|
||||
Three skips: the two existing long --finalize optimizer cases and the development-only
|
||||
Energy-Charts forecast case. All 128 active Energy-Charts regressions passed.
|
||||
|
||||
Independent package checks: JSON fix 49 tests; isolated measurement package 453 tests
|
||||
plus 5 documentation tests; capacity fixture isolation followed by 74 passing tests.
|
||||
Ruff and source formatting passed for the independent fix; measurement source Ruff
|
||||
passed. Full pinned Linux/Python 3.13 CI remains outstanding.
|
||||
|
||||
All original 102 saved file hashes and original feature HEAD were checked unchanged.
|
||||
Both PR worktrees are clean, locally committed, and unpublished. This enables small
|
||||
independent PRs now; it does not complete the still-open optimizer/PV/output port.
|
||||
|
||||
## First upstream PR published, 2026-09-16
|
||||
|
||||
Explicit user approval received for publishing the standalone JSON restore fix.
|
||||
Fetched main `4a37244` (dependency update #1321) and rebased the standalone branch;
|
||||
its new head is `bdc754d12fd08e0da18d3156642c695f4bf67bd2`. All 49 measurement tests,
|
||||
source Ruff and formatting checks passed again. Pushed only
|
||||
`fix/measurement-json-reload` and created [PR #1322](https://github.com/Akkudoktor-EOS/EOS/pull/1322)
|
||||
against main. Verified the remote head and PR patch: one commit, exactly two files.
|
||||
The other integration/measurement branches were not pushed. The PR is conflict-free,
|
||||
not merged; GitHub CI was started and is being checked. Original HEAD and all 102
|
||||
backup hashes were rechecked unchanged. Earlier notes saying all packages are
|
||||
unpublished are historical checkpoints; this section supersedes them for this fix.
|
||||
|
||||
## Parallel package preparation and compatibility
|
||||
|
||||
On the user's explicit request, independent PV and tariff ports and Optimize-mode
|
||||
compatibility coverage are being prepared in separate worktrees. The main/integration
|
||||
configuration prerequisite was refreshed to main4a37244 and PR1305head60b77f6;
|
||||
285 configuration/migration/Pydantic tests pass. The latest 1305 change only formats
|
||||
three files. See [PR integration matrix](pr-integration-matrix.md) for the seven
|
||||
remaining functional packages, existing upstream prerequisites, and combined
|
||||
Optimize acceptance gates. Parallel work is not authorization to publish every lane.
|
||||
|
||||
## Completed parallel checkpoint and first green CI
|
||||
|
||||
Source checkpoint b684748 now combines local PV, imported tariff protection,
|
||||
device physics/cache corrections and the confirmed Optimize failure-path fix.
|
||||
The combined selection passed 277 tests (3 regular skips); measurement APIs and
|
||||
persistence then passed 132 tests; regenerated documentation passed all 5 checks.
|
||||
These are targeted local checks, not a full integration CI run. The complete new
|
||||
GENETIC orchestration, config-owned request and result/PDF port remain outstanding.
|
||||
See the updated integration matrix for exact dependencies and limitations.
|
||||
|
||||
PR #1322 now has two commits through ce132ea. Its initial mypy error in a test's
|
||||
optional timestamp assertion was fixed; all current checks are green: 1,884 passed,
|
||||
16 skipped in pinned Linux/Python 3.13 pytest, plus pre-commit/mypy, CodeQL and
|
||||
Docker build. PR remains open and mergeable. Only this branch has been published;
|
||||
no merge or HA deployment occurred. The finite CI follow-up was paused after
|
||||
verification. Original feature HEAD and all 102 backed-up file hashes remain intact.
|
||||
@@ -0,0 +1,67 @@
|
||||
# EOS interface handoff to Home Assistant
|
||||
|
||||
2026-09-16 — complete EOS feature port prepared for review in eight PRs.
|
||||
|
||||
The combined branch is `feat/genetic-complete`, based on main `4a37244` and the
|
||||
prerequisite PRs. Use [review handoff](review-handoff.md) for merge order and current
|
||||
PR links, and [GENETIC rollout](genetic-rollout.md) for configuration and manual
|
||||
acceptance. Pin the final merged EOS commit after CI and installation acceptance;
|
||||
the earlier `integration/eos-consolidation-20260916` is a historical checkpoint.
|
||||
|
||||
- Configuration collections `devices.batteries`, `electric_vehicles`, `inverters`,
|
||||
`home_appliances` are maps keyed by stable device ID. A supplied `device_id` must
|
||||
match its map key; omitted IDs use that key. Old lists migrate. LCOS configuration
|
||||
uses `levelized_cost_of_storage_amt_kwh`; old files retain their values.
|
||||
- Algorithm settings are separate under `optimization.genetic` / `genetic0`.
|
||||
Existing main configuration uses `interval_sec` and `horizon_hours` there.
|
||||
Do not send feature-branch top-level interval/horizon settings without migration.
|
||||
- `#1305` runtime bulk/granular changes are retained above file/environment sources;
|
||||
config persistence is still an explicit existing save operation.
|
||||
- New measurement routes: PUT/GET `/v1/measurement/samples`, GET
|
||||
`/v1/measurement/energy`, GET `/v1/measurement/household`, POST
|
||||
`/v1/measurement/battery-capacity/{battery_id}`. OpenAPI describes request schemas.
|
||||
Sample times require timezone; values remain in declared raw units, derived energy
|
||||
is Wh and includes coverage/quality. Missing data is not implicitly zero energy.
|
||||
- Capacity estimates are separate evidence; even store_estimate=true never replaces
|
||||
devices.batteries[id].capacity_wh. Explicitly stored estimates survive runtime
|
||||
bulk changes; existing config save controls disk persistence.
|
||||
- Python measurement storage-facing methods are async and must be awaited. The HTTP
|
||||
schema remains ordinary JSON; HA does not need to mirror EOS internals.
|
||||
- Legacy POST `/optimize` remains GENETIC0. New POST `/v1/optimize` runs GENETIC
|
||||
from the typed EOS device configuration. Its body accepts runtime `soc`,
|
||||
`forecasts`, `start_solution` and `start_solution_datetime`; hardware overrides
|
||||
and query-string overrides are rejected. Request SoC is an integer percentage
|
||||
keyed by device ID; automatic
|
||||
measurement lookup uses recent `<device_id>-soc-factor` values from 0 to 1.
|
||||
Missing, stale, future or invalid observations fail instead of implying zero.
|
||||
- GENETIC supports 900/3600-second slots. Provider power in W is converted once to
|
||||
Wh per slot; runtime forecast arrays are already Wh per slot and prices per Wh.
|
||||
Runtime arrays begin at local midnight. Missing control forecasts fail the run;
|
||||
shorter forecast tails are clipped with diagnostics. Explicit/imported sale
|
||||
prices, including zero and negative values, remain authoritative.
|
||||
- The new optimizer includes timestamp-aligned warmstarts, opt-in battery export,
|
||||
EV deadlines, flexible consumer profiles and per-cycle windows/completed cycles.
|
||||
AUTO/FIXED terminal value and forecast-tail diagnostics affect scoring, never
|
||||
extend the executable control horizon, and remain separate from battery wear.
|
||||
- Automatic GENETIC runs use the site's timezone derived from its coordinates;
|
||||
explicit run starts and warmstart timestamps retain their timezone/instant.
|
||||
Configure device IDs and schedules against this timezone, including DST.
|
||||
- GET `/v1/energy-management/optimization/solution/{algorithm}` returns the stored
|
||||
algorithm-specific result. Native/generic results and execution plans publish
|
||||
atomically for the successful run. Failed Optimize calls return errors rather
|
||||
than a previous successful result.
|
||||
- GET `/v1/energy-management/optimization/solution/GENETIC/pdf` renders the stored
|
||||
GENETIC snapshot on demand (404 before a result exists). The legacy PDF endpoint
|
||||
and GENETIC0 implementation remain separate. The local calibrated Akkudoktor PV
|
||||
backend and the measurement APIs are included in the prerequisite PRs.
|
||||
|
||||
No HA repository changes, lab deployment, real device control or production config
|
||||
were performed. Retire the private HA core only after its differences are audited
|
||||
and a final EOS commit passes the full feature/API acceptance scenarios.
|
||||
|
||||
GENETIC currently supports one inverter, one stationary battery, one EV and multiple
|
||||
household appliances. Unsupported device counts or inconsistent inverter/battery
|
||||
links are rejected. Verify both 15- and 60-minute Optimize runs, fresh measurements,
|
||||
tariff units, result/plan timestamps and reports in the actual HA installation.
|
||||
EOS code and synthetic scenarios are automated-test coverage; they do not validate
|
||||
HA entities, physical hardware or the remaining private HA-core differences.
|
||||
@@ -0,0 +1,93 @@
|
||||
# GENETIC configuration and manual acceptance
|
||||
|
||||
Apply the dependencies in [review handoff](review-handoff.md) before the complete
|
||||
GENETIC PR. These changes implement the feature branch on current EOS interfaces;
|
||||
they do not migrate a running Home Assistant installation automatically.
|
||||
|
||||
## Configuration
|
||||
|
||||
Hardware and schedules belong in the typed `devices` maps, keyed by stable device
|
||||
IDs. Configure an inverter and link its `battery_id` to the configured stationary
|
||||
battery, or leave it empty when there is no battery. GENETIC currently supports one
|
||||
inverter, one stationary battery, one EV and multiple household appliances. Explicit
|
||||
validation rejects unsupported device counts and inconsistent links.
|
||||
|
||||
Example optimization settings (merge into an otherwise complete configuration):
|
||||
|
||||
```json
|
||||
{
|
||||
"optimization": {
|
||||
"algorithm": "GENETIC",
|
||||
"genetic": {
|
||||
"interval_sec": 900,
|
||||
"horizon_hours": 24,
|
||||
"tail_horizon_hours": 48,
|
||||
"terminal_value_mode": "AUTO",
|
||||
"measurement_max_age_seconds": 300
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Use `interval_sec: 3600` for hourly operation. AUTO evaluates available forecast
|
||||
continuation; FIXED uses `terminal_value_euro_per_kwh`. Battery wear/LCOS remains a
|
||||
separate cost. The tail affects scoring, never the emitted control horizon.
|
||||
`prediction.hours` must cover the control horizon; shorter available tails are
|
||||
clipped with diagnostics. Missing control forecasts cancel the run.
|
||||
|
||||
Old feature settings such as `optimization.interval` and flat terminal-value fields
|
||||
migrate into `optimization.genetic`; explicit nested settings win. Check the saved
|
||||
configuration after migration. GENETIC0 retains its separate settings and `/optimize` API.
|
||||
|
||||
Automatic GENETIC runs use the site's timezone derived from its coordinates, even
|
||||
when the server runs in UTC. An explicitly supplied run start retains its timezone.
|
||||
Stored results and warmstarts retain explicit timezones and absolute instants.
|
||||
|
||||
## Requests and measurements
|
||||
|
||||
`POST /v1/optimize` runs GENETIC from configuration. An empty JSON object uses the
|
||||
configured forecasts and fresh measurements. Runtime input may contain `soc`,
|
||||
`forecasts`, `start_solution` and `start_solution_datetime`. Hardware overrides in
|
||||
this body and query-string overrides are rejected. For example, with a configured
|
||||
device ID `storage`:
|
||||
|
||||
```json
|
||||
{"soc": {"storage": 42}}
|
||||
```
|
||||
|
||||
Request SoC values are integer percentages. Without an override, the measurement
|
||||
key `<device_id>-soc-factor` must contain a recent factor from 0 to 1. Invalid,
|
||||
future or stale measurements never become an assumed zero SoC. Completed appliance
|
||||
cycles use their configured measurement key, default `<device_id>.cycles_completed`.
|
||||
|
||||
Optional forecast arrays begin at local midnight, with one value per configured
|
||||
slot: `pv_forecast_wh` and `total_load` are Wh per slot; `electricity_price_per_wh`
|
||||
and `feed_in_tariff_per_wh` are currency per Wh. Provider PV/load power in W is
|
||||
converted by the resolver. Supplied/imported sale tariffs are never replaced by
|
||||
purchase prices. Missing optional arrays come from the selected providers.
|
||||
|
||||
Successful requests return the native result for that run. A failed run returns an
|
||||
error and cannot masquerade as a cached success. Generic solutions, plans and reports
|
||||
are derived from the same stored result. Warmstarts retain their source time so a
|
||||
later run shifts the previous controls to the new slot origin.
|
||||
|
||||
Retrieve the new GENETIC report with
|
||||
`GET /v1/energy-management/optimization/solution/GENETIC/pdf`. It renders the stored
|
||||
snapshot on demand; a missing result returns 404. The legacy PDF URL remains unchanged.
|
||||
|
||||
## Manual acceptance after merge
|
||||
|
||||
1. Back up the running configuration and update all merged EOS packages together.
|
||||
2. Confirm device IDs, inverter linkage, capacities, efficiencies, import/export
|
||||
limits, tariff units and the battery-export setting against your actual hardware.
|
||||
3. Check fresh SoC measurements and forecast coverage, then run Optimize at 60 and
|
||||
15 minutes. Inspect timestamps, slot energies, native/generic results and the PDF.
|
||||
4. Compare AUTO and FIXED terminal value with identical inputs. Tail diagnostics
|
||||
must not appear as extra commands; sale prices must retain their configured signs.
|
||||
5. Exercise an EV departure and a flexible consumer schedule, including a completed
|
||||
cycle. Check permitted windows, required energy and device commands in your setup.
|
||||
6. Make a measurement stale or omit control forecast coverage and confirm the request
|
||||
fails explicitly. Verify the legacy GENETIC0 endpoint if your installation uses it.
|
||||
|
||||
Automated checks cover modeled behavior. The final manual test validates the actual
|
||||
HA entities, provider data and physical installation.
|
||||
@@ -0,0 +1,25 @@
|
||||
# fix(optimization): reject invalid imported feed-in tariffs without fallback
|
||||
|
||||
Published with user approval as [PR #1324](https://github.com/Akkudoktor-EOS/EOS/pull/1324).
|
||||
Branch `fix/imported-feedin-main`, head `2a3b961`, base main `4a37244`.
|
||||
Two commits, two changed files. Original contributions from #1224/#1304 are credited.
|
||||
|
||||
GENETIC preparation now cancels if FeedInTariffImport cannot supply a finite
|
||||
one-dimensional tariff array matching the forecast length. It keeps the configured
|
||||
provider instead of switching to demo tariffs. Positive, zero and negative valid
|
||||
amount/Wh revenues remain unchanged. Other providers keep their fallback behavior.
|
||||
|
||||
Publication check: 68 passed, 2 regular long-running tests skipped; source Ruff,
|
||||
format and diff checks passed. Scoped mypy passed for the two changed files with
|
||||
transitive imports/untyped dependency diagnostics excluded. Full pinned Linux CI: 1921 passed, 16 skipped;
|
||||
pre-commit including full mypy, CodeQL and Docker passed.
|
||||
Regression coverage includes seven provider identities, simulation arithmetic and
|
||||
actual timestamped imports. Eleven invalid-input regressions fail on unchanged main.
|
||||
|
||||
The existing forward-fill path is unchanged: validation of its resulting array
|
||||
does not establish raw timestamp coverage or freshness. Feature direct-marketing
|
||||
overrides and quarter-hour orchestration remain part of the later GENETIC port.
|
||||
Legacy /optimize and GENETIC0 are unchanged. The source fix is already integrated
|
||||
with PV, device/configuration and Optimize-result packages in local combined tests.
|
||||
|
||||
No merge or deployment. All current-head checks completed successfully.
|
||||
@@ -0,0 +1,38 @@
|
||||
# feat(measurement): add typed energy, quality and capacity APIs
|
||||
|
||||
Local branch: `feat/measurement-energy-quality-capacity`.
|
||||
Review base: `feat/config-integration-base` (`9038b65`).
|
||||
Eventual target: official main, after its configuration prerequisites land.
|
||||
Status: published as [PR #1326](https://github.com/Akkudoktor-EOS/EOS/pull/1326), head `635ff2d`, against the
|
||||
prerequisite branch.
|
||||
|
||||
## Proposed PR body
|
||||
|
||||
Add typed measurement channels with explicit units and timestamp semantics, sample
|
||||
quality, energy integration, household energy balances and battery capacity estimates.
|
||||
Adapt persistence and REST access to main's asynchronous storage. Battery estimates
|
||||
use keyed device identities and remain separate from the configured active capacity;
|
||||
storing an estimate requires an explicit request and preserves runtime config updates.
|
||||
|
||||
Expose `/v1/measurement/samples`, `/v1/measurement/energy`,
|
||||
`/v1/measurement/household` and `/v1/measurement/battery-capacity/{battery_id}`.
|
||||
Regenerate the configuration and OpenAPI contracts. Use synthetic data only.
|
||||
|
||||
Validation: 453 configuration/measurement/device simulation tests and 5 documentation
|
||||
tests pass. A further 74 measurement/capacity tests pass after carrying over fixture
|
||||
isolation. Ruff passes for measurement source and the measurement REST module.
|
||||
Final pinned Linux/Python 3.13 CI: 2046 passed, 16 skipped; pre-commit with full mypy and Docker passed.
|
||||
CodeQL becomes applicable after retargeting to main.
|
||||
|
||||
Depends on the device maps/converters in #1256, runtime configuration in #1305 and
|
||||
local fixes for stable device IDs, LCOS migration and charge-rate compatibility.
|
||||
Includes the independently prepared JSON restore fix; it should land separately first.
|
||||
No new GENETIC orchestration or battery/inverter physics is included in this branch.
|
||||
|
||||
## Submission gate
|
||||
|
||||
Do not open this whole branch against main now: its ancestry still includes the
|
||||
unmerged configuration PRs. Preserve those contributors' existing PRs and credit.
|
||||
Once prerequisites are merged, rebuild/rebase the measurement package onto that
|
||||
main, inspect the resulting diff and rerun combined tests and CodeQL before merging.
|
||||
The comparison to `feat/config-integration-base` isolates today's measurement work.
|
||||
@@ -0,0 +1,41 @@
|
||||
# fix(measurement): restore JSON records into the existing singleton
|
||||
|
||||
Target: `Akkudoktor-EOS/EOS:main`.
|
||||
Local branch: `fix/measurement-json-reload`.
|
||||
Local head: `ce132ea` (based on main `4a37244`).
|
||||
Status: published with explicit user approval as [PR #1322](https://github.com/Akkudoktor-EOS/EOS/pull/1322).
|
||||
Two commits, two files; published head and diff verified. Not merged.
|
||||
The second commit adds an explicit non-null timestamp assertion after CI mypy
|
||||
flagged the test. All 49 local tests still pass. Pre-commit (including mypy),
|
||||
CodeQL and Docker build passed on ce132ea. Full pinned Linux/Python 3.13 CI pytest
|
||||
also passed: 1,884 passed, 16 skipped, including --finalize and config side-effect
|
||||
checks (run 35118801197). PR remains open and mergeable; no merge performed.
|
||||
|
||||
## Proposed PR body
|
||||
|
||||
When measurement persistence falls back to JSON, loading a saved file reports success
|
||||
but does not restore its records: validating a second `Measurement` returns the
|
||||
existing singleton. Parse and validate the individual records before inserting them
|
||||
into that singleton. Invalid files now return `False` instead of reporting success.
|
||||
|
||||
Regression coverage checks round trips, timestamp preservation, repeated loading,
|
||||
merging with existing timestamps, malformed files without partial validation writes,
|
||||
and database-provider precedence. Four regression cases fail on unchanged main.
|
||||
With the fix, all 49 measurement tests pass.
|
||||
|
||||
Validation: `python -m pytest tests/test_measurement_file_restore.py tests/test_measurement.py -q`;
|
||||
Ruff check and format check of the changed source; `git diff --check`.
|
||||
Run locally on Windows/Python 3.11.9, followed by successful pinned Linux/Python 3.13
|
||||
CI and its complete test suite as recorded above.
|
||||
|
||||
No settings or API schema changes. This fix is independent of #1256, #1305 and the
|
||||
GENETIC port.
|
||||
|
||||
## Exact review scope
|
||||
|
||||
- `src/akkudoktoreos/measurement/measurement.py`
|
||||
- `tests/test_measurement_file_restore.py`
|
||||
|
||||
Only these two files differ from the pinned main. Do not publish the integration
|
||||
branch as part of this PR. Publication approval was received on 2026-09-16. Only this named branch was pushed.
|
||||
Inspect CI and review before any merge; merging was not part of this publication request.
|
||||
@@ -0,0 +1,24 @@
|
||||
# fix(optimization): return only the current completed Optimize result
|
||||
|
||||
Published with user approval as [PR #1323](https://github.com/Akkudoktor-EOS/EOS/pull/1323).
|
||||
Branch: `fix/optimize-run-result`; base main `4a37244`; head `ef8d913`.
|
||||
Three commits, three changed files. No merge or deployment.
|
||||
|
||||
A failed explicit optimization previously returned an old cached solution as HTTP
|
||||
200. Conversion failures could publish a new native result alongside the previous
|
||||
generic result and plan. Return this run's completed solution directly to the route;
|
||||
build all three representations before publishing them together. Preserve previous
|
||||
consistent results after optimizer/conversion errors and skip the failed run's
|
||||
control dispatch. Legacy `/optimize` remains GENETIC0; automatic mode keeps its
|
||||
configured algorithm selection. No optimizer mathematics or slot behavior changes.
|
||||
|
||||
Validation: 38 tests passed, 2 regular long-running tests skipped. All 22 new
|
||||
regression cases passed again after typing dynamic test keyword arguments. Source
|
||||
Ruff, formatting and diff checks passed. Scoped mypy passed for all three changed
|
||||
files (transitive imports/untyped dependency diagnostics excluded locally).
|
||||
Pinned Linux CI: 1908 passed, 16 skipped; pre-commit including full mypy, CodeQL and Docker passed. Thirty
|
||||
regressions also passed separately in UTC and Europe/Berlin; timezone expectations are now explicit.
|
||||
|
||||
The fix is already combined with PV, tariff and device packages in the integration
|
||||
branch. Integration also carries the test annotation correction. Independent of
|
||||
`#1322`, #1256 and #1305. Original working copy remains untouched.
|
||||
@@ -0,0 +1,125 @@
|
||||
# Remaining EOS packages and Optimize compatibility
|
||||
|
||||
Historical planning snapshot. The remaining packages below are now implemented;
|
||||
see [review handoff](review-handoff.md) for current dependencies and acceptance.
|
||||
|
||||
Snapshot: 2026-09-16. Official main: `4a37244`. Feature source: `d2e2d58`, plus
|
||||
separately backed-up local work. This is a functional package estimate, not a claim
|
||||
that every differing commit requires its own PR.
|
||||
|
||||
## What is still missing on main
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
| Package | Missing behavior relative to feature/local work | Local state | Dependency |
|
||||
| --- | --- | --- | --- |
|
||||
| Device physics | Slot-duration-aware battery/inverter flows, export control, efficiency and limits | Published as #1327 against the configuration prerequisite branch; combined in integration | #1256 device settings/converters |
|
||||
| Complete GENETIC | Quarter-hour orchestration, adaptive evolution, export states, warmstart alignment, forecast tail/terminal value, EV deadlines and flexible consumer profiles | Physics and primitives exist; orchestration/parameter/output integration remains open | Device physics, #1256, tariff contract |
|
||||
| Imported tariff protection | Preserve supplied/imported revenue; avoid silent demo or market-price replacement | Published as #1324 and combined in integration; feature-specific override still required inside GENETIC port | Main patch independent; second part belongs with GENETIC |
|
||||
| Local calibrated PV | Local Akkudoktor PV calculation, measurement calibration and outage handling under existing provider ID | Published as #1325 against main; combined in integration | Provider-specific settings; combined forecast/optimizer acceptance later |
|
||||
| Measurement APIs | Typed channels, quality, energy integration, household balance and capacity estimate APIs | Published as #1326 against the configuration prerequisite branch | #1256, #1305, configuration corrections; JSON fix #1322 |
|
||||
| Config-owned Optimize request | Local ConfigOptimizationRequest, /v1/optimize, runtime observations and common parameter resolver | Backed up; async/maps/converters adaptation pending | New GENETIC and #1305 |
|
||||
| Result/PDF output | Quarter-hour, flexible-consumer, export, tail/rest-value diagnostics in main's on-demand algorithm-specific output | Pending | Final GENETIC result contract |
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
Four of the seven feature packages are now published as #1324–#1327. Three broader
|
||||
packages remain unported: complete GENETIC, the config-owned Optimize API, and result/PDF
|
||||
output. Their final PR split depends on the resulting contracts. #1256 and #1305 are existing
|
||||
foundation PRs, not two newly invented replacements. #1224/#1304 already address
|
||||
parts of the tariff work against the old feature branch; preserve/reconcile those
|
||||
contributions rather than count duplicate implementations as separate deliverables.
|
||||
PR #1322 is already published and is additional to this feature table.
|
||||
|
||||
One additional standalone defect fix is published as PR #1323, fix/optimize-run-result:
|
||||
an explicit Optimize request must return only its own completed result. Cache
|
||||
method identity was also corrected as a prerequisite within the device package;
|
||||
it does not currently add another planned feature PR.
|
||||
|
||||
Local helper scripts and private HA-core divergence are not silently included in this
|
||||
count. They remain separately secured/to be audited. Changelog/release work follows
|
||||
acceptance; it is not another optimizer implementation.
|
||||
|
||||
## Parallel lanes
|
||||
|
||||
- Local PV: `feat/local-pv-main-port`, sibling worktree `EOS-pr-local-pv`.
|
||||
- Tariff preparation: `fix/imported-feedin-main`, sibling `EOS-pr-feedin-main`.
|
||||
- Device physics: `feat/slot-device-physics`, sibling `EOS-pr-device-physics`.
|
||||
- Optimize failure correction: `fix/optimize-run-result`, sibling
|
||||
`EOS-reference-optimize-main` (now a named review branch).
|
||||
- Optimize compatibility tests: `test/optimize-pr-contracts`, sibling
|
||||
`EOS-pr-optimize-contracts`. These are shared acceptance coverage, not necessarily
|
||||
an extra standalone public PR.
|
||||
- Root/integration: configuration prerequisites, shared API/algorithm contracts and
|
||||
eventual combination of the tested packages.
|
||||
|
||||
Do not have multiple lanes independently rewrite geneticparams.py, EMS.run or the
|
||||
same configuration structure. A tested tariff patch will be carried into the core
|
||||
port; the core port must keep its regression cases. PV keeps the public
|
||||
PVForecastAkkudoktor ID and existing remote behavior unless explicitly selected.
|
||||
Parallel preparation does not imply parallel unreviewed merges or publishing all
|
||||
branches. The JSON fix #1322 and subsequently the Optimize fix #1323 have publication
|
||||
approval. Tariff fix #1324 was subsequently authorized and published. The user then
|
||||
authorized all prepared packages: PV #1325, measurement #1326 and device physics
|
||||
`#1327` are also published. The latter two target the explicit configuration comparison
|
||||
branch 9038b65 pending their prerequisites. No upstream merges were performed.
|
||||
|
||||
## Three different Optimize contracts
|
||||
|
||||
1. Legacy POST `/optimize` on main explicitly runs GENETIC0, hourly. Existing payload
|
||||
and legacy response aliases must keep working regardless of configured default.
|
||||
2. Automatic EMS with `ems.mode=OPTIMIZATION` selects `optimization.algorithm`:
|
||||
GENETIC or GENETIC0. Preparation and solution conversion are asynchronous.
|
||||
PREDICTION and DISABLED must not accidentally run optimization or dispatch controls.
|
||||
3. The feature worktree's LOCAL POST `/v1/optimize` and ConfigOptimizationRequest are
|
||||
not present on main/integration yet. They must be adapted to current maps,
|
||||
converters and algorithm-specific settings. Old feature `/optimize` meant a
|
||||
different optimizer; clients need explicit migration, not a silent route switch.
|
||||
|
||||
Current blockers: GENETIC.prepare still forces interval_sec to 3600 and EMS start
|
||||
alignment floors to the hour. Fifteen-minute device tests do not prove quarter-hour
|
||||
Optimize-mode support. The core package must change preparation, slot alignment,
|
||||
optimization and response metadata together.
|
||||
|
||||
Confirmed on unchanged main 4a37244: after a failed explicit optimization, the HTTP
|
||||
route returned the previous stored solution with HTTP 200. Conversion errors could
|
||||
also publish a new native result alongside an old generic result/plan. The local
|
||||
fix prepares all three before publishing and returns the successful current-run
|
||||
result directly to the route. Errors retain the previous coherent trio, restore
|
||||
IDLE and do not dispatch controls for that failed optimization. Strict passing
|
||||
regression tests replace the initial expected-failure audit cases.
|
||||
|
||||
## Shared acceptance before dependent PRs can land
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
| Area | Required combined check |
|
||||
| --- | --- |
|
||||
| Routing | Legacy /optimize remains GENETIC0; automatic mode selects the configured algorithm; the new explicit API selects GENETIC deliberately |
|
||||
| Configuration | Stable device IDs/maps and converters, runtime changes retained, old aliases migrated without losing values |
|
||||
| Time | 900/3600-second slots, non-hour-aligned start and advancing warmstart, timezone/DST boundaries, matching output timestamps |
|
||||
| Units | PV/load predictions are W; integrate once to slot Wh. `feed_in_tariff_wh` and `elecprice_marketprice_wh` already yield amount/Wh; convert amount/kWh configuration exactly once |
|
||||
| Tariffs | Positive/zero/negative/imported revenue remains distinct from purchase cost; missing or invalid imported data does not silently become demo data |
|
||||
| Devices | SOC/energy balance, charge/discharge and inverter limits, allowed/blocked battery export |
|
||||
| Consumers | Feature profiles/deadlines and #1256 per-cycle windows/gaps both preserved; impossible schedules fail explicitly |
|
||||
| Results | Raw algorithm result, generic optimization solution, execution plan and on-demand PDF agree on slots and device IDs |
|
||||
| Errors | Failed preparation/optimization produces no new control dispatch and no misleading fresh-success response using old results |
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
A passing individual PR is insufficient: after combining dependent packages, run
|
||||
these synthetic end-to-end API cases together with the GENETIC0 regression suite.
|
||||
No device control, HA deployment or production configuration is part of this work.
|
||||
|
||||
## Completed combined check
|
||||
|
||||
Integration source checkpoint b684748 combines tariff b2a4e2f, Optimize fix 8ed65ec,
|
||||
device/cache corrections be184a6 and 38eb4ad, and local PV 84abe05, on the refreshed
|
||||
configuration base. The combined API failure/algorithm-selection, tariff, cache,
|
||||
battery/inverter, PV, configuration/migration and both optimizer test selection
|
||||
passed: **277 passed, 3 regular skips**. No expected-failure markers were used to
|
||||
hide Optimize defects. XML: private backup integration-parallel-compatibility.xml.
|
||||
The complete measurement/channel/energy/household/capacity selection additionally
|
||||
passed **132 tests** on this combined source checkpoint, including JSON persistence.
|
||||
|
||||
This is local Windows/Python 3.11 verification, not full pinned CI or acceptance of
|
||||
the pending new GENETIC. The wider standalone PV suite separately reproduced an
|
||||
existing Windows file-timestamp test failure on unchanged main; that test was
|
||||
explicitly excluded from its reported 164-passing selection. Forecast retention
|
||||
does not establish complete horizon coverage; that remains a core-port gate.
|
||||
@@ -0,0 +1,134 @@
|
||||
# EOS: Arbeitsstand und Weg zu kleinen PRs
|
||||
|
||||
Historischer Zwischenstand. Die damals offenen GENETIC-Pakete sind inzwischen
|
||||
implementiert. Maßgeblich sind [Review-Handoff](review-handoff.md) für die acht PRs,
|
||||
Abhängigkeiten und Merge-Reihenfolge sowie [GENETIC-Rollout](genetic-rollout.md)
|
||||
für Konfiguration und manuelle Abnahme. Die Statusangaben unten dokumentieren
|
||||
frühere Arbeitsschritte.
|
||||
|
||||
Stand: 16.09.2026. Offizielles main für PR #1322: `4a37244`.
|
||||
Die lokale Integration enthält ebenfalls diesen main-Stand und den aktualisierten
|
||||
Stand von #1305 (`60b77f6`).
|
||||
|
||||
## Was jetzt möglich ist
|
||||
|
||||
Ein unabhängiger, lokal getesteter PR ist veröffentlicht: `fix/measurement-json-reload`
|
||||
auf aktuellem main. Sein Worktree ist `../EOS-pr-measurement-json`; er enthält nur
|
||||
zwei geänderte Dateien. Der veröffentlichte [PR #1322](https://github.com/Akkudoktor-EOS/EOS/pull/1322)
|
||||
enthält zwei Commits bis `ce132ea`. Der PR-Text steht in
|
||||
[measurement-json-reload.md](pr-drafts/measurement-json-reload.md).
|
||||
|
||||
Das ist ein konkreter Einstieg in den PR-Workflow. Die vollständige Übernahme aller
|
||||
Funktionen aus dem alten Feature-Branch ist noch NICHT abgeschlossen.
|
||||
|
||||
## Branches und ihre Aufgaben
|
||||
|
||||
<!-- pyml disable line-length -->
|
||||
| Branch | Zweck | Freigabezustand |
|
||||
| --- | --- | --- |
|
||||
| `fix/measurement-json-reload` | Kleiner JSON-Ladefehler direkt auf main | Veröffentlicht als #1322; gesamte CI grün, noch nicht gemergt |
|
||||
| `feat/config-integration-base` | Zusammengeführte #1256/#1305 plus Integrationskorrekturen | Veröffentlichter Vergleichsbranch 9038b65; kein konkurrierender Sammel-PR |
|
||||
| `feat/measurement-energy-quality-capacity` | Messdatenfunktionen ohne neue Optimiererphysik | PR #1326 gegen Konfigurationsbasis; später auf main umstellen |
|
||||
| `fix/imported-feedin-main` | Importierte Einspeisetarife erhalten und prüfen | Veröffentlicht als #1324; CI läuft |
|
||||
| `feat/local-pv-main-port` | Lokale PV-Prognose und Kalibrierung | PR #1325 gegen main |
|
||||
| `feat/slot-device-physics` | Slotphysik und getrennte Cache-Methoden | PR #1327 gegen Konfigurationsbasis; später auf main umstellen |
|
||||
| `fix/optimize-run-result` | Nur das Ergebnis des erfolgreichen aktuellen Laufs zurückgeben | Veröffentlicht als #1323; CI läuft |
|
||||
| `integration/eos-consolidation-20260916` | Zusammenführung und Prüfung aller Portierungspakete | Unvollständig; kein Gesamt-PR und kein HA-Release |
|
||||
| `feat/direct-marketing-battery-grid-export` | Ursprüngliche Entwicklung mit lokalen Änderungen | Unverändert erhalten und gesichert |
|
||||
<!-- pyml enable line-length -->
|
||||
|
||||
Der Worktree `../EOS-pr-measurement` gehört zum Messdatenpaket.
|
||||
`../EOS-integration-20260916` bleibt der zeitlich begrenzte Portierungsarbeitsplatz.
|
||||
`../EOS-reference-20260916` bleibt der unveränderte Vergleichsstand für Basisfehler.
|
||||
Ein Worktree ist nur ein Arbeitsverzeichnis; Gegenstand eines PRs ist der Branch.
|
||||
|
||||
## Umgesetzt und geprüft
|
||||
|
||||
- Geräte-Maps, Algorithmuskonvertierung und Laufzeitkonfiguration aus #1256/#1305.
|
||||
- Korrekturen für stabile Geräte-IDs, LCOS-Migration und Ladeleistungslisten.
|
||||
- Messkanäle, Qualität, Energieintegration, Haushaltsbilanz und Kapazitätsschätzung,
|
||||
einschließlich asynchroner Speicherung und REST-Schnittstellen.
|
||||
- Im Integrationsbranch außerdem Viertelstunden-Gerätephysik, begrenzter
|
||||
Batterieexport und Wirkungsgrade; Restwert-/Prognose-Nachlauf-Bausteine.
|
||||
- GENETIC0 bleibt separat. Sein `/optimize`-Endpunkt beweist keine vollständige
|
||||
Portierung des neuen GENETIC.
|
||||
|
||||
## Noch offen
|
||||
|
||||
1. Neues GENETIC vollständig auf main-Strukturen anpassen: Viertelstundenplanung,
|
||||
Exportzustände, adaptive Evolution und zeitlich korrekter Warmstart.
|
||||
2. Flexible Lastprofile/EV-Fristen mit den Mehrfachzyklen und Zeitfenstern aus
|
||||
`#1256` verbinden. Beide vorhandenen Funktionssätze müssen erhalten bleiben.
|
||||
3. Horizont, Prognoselücken, Nachlauf und Restwert mit Optimierer und Ergebnissen
|
||||
verdrahten; bisher sind nur die Bausteine übernommen.
|
||||
4. Den bereits portierten Tarifschutz auch in der neuen GENETIC-Parametervorbereitung
|
||||
erhalten; dort Prognosegrenzen und Lücken verbindlich prüfen.
|
||||
5. Algorithmusspezifische PDF-Ausgabe und die lokale Konfigurationslern-Anfrage
|
||||
integrieren. Die lokale kalibrierte PV-Prognose ist inzwischen portiert.
|
||||
6. Gesamtabnahme einschließlich API-Weg des neuen GENETIC und gepinnter CI.
|
||||
Danach erst Übergabe eines festen EOS-Commits an HA und Release-Arbeiten.
|
||||
|
||||
## PR-Reihenfolge
|
||||
|
||||
1. JSON-Fix als PR #1322 veröffentlicht: CI und Review prüfen, danach über Merge entscheiden.
|
||||
2. `#1256/#1305` über ihre vorhandenen PRs zusammenführen; lokale Korrekturen dort
|
||||
zuordnen. Keine pauschale Veröffentlichung der kombinierten Integrationsbasis.
|
||||
3. Das isolierte Messdatenpaket auf diesen main-Stand setzen, Diff prüfen und
|
||||
nochmals testen; dann als eigenen PR einreichen.
|
||||
4. Optimierer, Tarifschutz, PV und Ausgabe jeweils als abgegrenzte Pakete fertigstellen.
|
||||
Abhängige PRs ausdrücklich als solche behandeln.
|
||||
|
||||
Für jede neue unabhängige Änderung: aktuellen `refs/remotes/origin/main` holen,
|
||||
einen Themenbranch mit eigenem Worktree starten, lokal testen, den Diff prüfen,
|
||||
dann PR gegen main. Nach Review und grüner CI mergen. Alte Worktrees erst nach
|
||||
abgeschlossener Übernahme und Prüfung lokaler Änderungen aufräumen.
|
||||
|
||||
Wegen der vorhandenen gleichnamigen lokalen Branch-Referenz ausdrücklich
|
||||
`refs/remotes/origin/main` verwenden. Keine neuen unabhängigen Funktionen auf den
|
||||
alten großen Feature-Branch oder die Integrationsbasis stapeln.
|
||||
|
||||
## Kann die laufende Entwicklung schon umziehen?
|
||||
|
||||
Unabhängige Fehlerkorrekturen und neue Funktionen können ab jetzt in Themenbranches
|
||||
auf main erfolgen. Für Entwicklung, die den vollständigen neuen GENETIC oder die
|
||||
noch fehlenden Funktionen benötigt, ist der Integrationsstand noch nicht abgenommen.
|
||||
Die ursprüngliche Arbeitskopie bleibt erhalten. JSON-Fix #1322, Optimize-Fix #1323
|
||||
und Tarifschutz #1324 sind veröffentlicht. Auf weitere Freigabe folgten PV #1325,
|
||||
Messdaten #1326 und Gerätephysik #1327; nichts wurde gemergt oder deployt.
|
||||
Der aktuelle Review-Überblick steht in [review-handoff.md](review-handoff.md).
|
||||
|
||||
## HA-Übergabe
|
||||
|
||||
Noch keinen neuen Gesamtstand pinnen oder deployen. Die geplante Schnittstelle nutzt
|
||||
Geräte-Maps mit stabilen IDs, `levelized_cost_of_storage_amt_kwh`, asynchrone
|
||||
Messdatenzugriffe und getrennte GENETIC/GENETIC0-Pfade. Details stehen in
|
||||
[eos-ha-handoff.md](eos-ha-handoff.md). HA-Dateien wurden nicht verändert.
|
||||
|
||||
## Nachweise und Grenzen
|
||||
|
||||
Der JSON-PR: 49 bestandene Tests, Ruff und Formatprüfung.
|
||||
Das isolierte Messdatenpaket: 453 bestandene Tests plus 5 Dokumentationstests;
|
||||
74 Tests nach Übernahme der Fixture-Isolation nochmals erfolgreich.
|
||||
XML-Protokolle liegen in der privaten Sicherung `eos-20260916-120324`.
|
||||
Für PR #1322 ist die gepinnte Linux/Python-3.13-CI inzwischen bestätigt:
|
||||
1.884 Tests bestanden, 16 übersprungen; Pre-commit/Mypy, CodeQL und Docker-Build
|
||||
erfolgreich auf `ce132ea`. Die aktuellen CI-Ergebnisse aller sechs PRs stehen im Review-Handoff.
|
||||
|
||||
Zusätzlicher Integrationslauf: 764 Tests bestanden, 3 übersprungen; zwei zunächst
|
||||
fehlgeschlagene Dokumentationsvergleiche betrafen ausschließlich die Versionsangabe.
|
||||
Nach Neugenerierung bestanden alle 5 Dokumentationstests. Darunter sind außerdem
|
||||
128 bestandene Energy-Charts-Regressionen zum neuen main-Commit dokumentiert.
|
||||
|
||||
Früherer gemeinsamer Source-Stand `b684748`: 277 Tests bestanden, 3 regulär
|
||||
übersprungen, für PV, Tarifschutz, Gerätephysik, Cache, Konfiguration und beide
|
||||
bisherigen Optimierer einschließlich API-Fehlerbehandlung. Anschließend bestanden
|
||||
alle 132 Messdaten-/Haushalts-/Kapazitätsprüfungen auf diesem gemeinsamen Stand.
|
||||
Die vollständige neue GENETIC-Orchestrierung bleibt offen. Pakete und
|
||||
Kompatibilitätsbedingungen stehen in [pr-integration-matrix.md](pr-integration-matrix.md).
|
||||
Die neu generierte gemeinsame Dokumentation besteht ebenfalls alle fünf Prüfungen.
|
||||
|
||||
Aktueller Abschluss: Alle sechs veröffentlichten PRs haben ihre vorgesehenen
|
||||
GitHub-Prüfungen bestanden. Gemeinsamer Stand: 253 Dateien ohne Mypy-Fehler,
|
||||
37 gezielte Nachprüfungen und vollständiger Sphinx-Build erfolgreich. Die Grenzen
|
||||
des Windows-Gesamtlaufs und die nachgewiesenen main-Baselinefehler sind im
|
||||
[Review-Handoff](review-handoff.md) dokumentiert. Nichts wurde gemergt oder deployt.
|
||||
@@ -0,0 +1,60 @@
|
||||
# EOS review and merge handoff
|
||||
|
||||
The consolidation implements the remaining GENETIC optimizer, configuration-owned
|
||||
Optimize request and result/PDF output. See [GENETIC rollout](genetic-rollout.md)
|
||||
for configuration and manual acceptance. Historical planning documents in this
|
||||
directory describe earlier checkpoints; this handoff supersedes their pending-work lists.
|
||||
|
||||
## Integration status
|
||||
|
||||
The seven prerequisite packages #1322-#1328 are merged into main. PR #1329 was
|
||||
merged into `integration/genetic-prerequisites`, not into main. The final delivery
|
||||
branch `feat/genetic-complete-main-port` brings that complete implementation directly
|
||||
to main. Until that final PR is merged, main lacks the complete GENETIC port.
|
||||
|
||||
The foundation preserves the original #1256/#1305 contributions and compatibility
|
||||
corrections; do not merge those original PRs again as extra prerequisites.
|
||||
|
||||
Main `3c86254` has exactly the production source tree of the original prerequisite
|
||||
integration `5eacd54`. Only generated API version strings and one corrected test
|
||||
import differ. The final delivery preserves the complete production source and
|
||||
tests from #1329, including that corrected import, and regenerates API/configuration
|
||||
documents from the combined code. Its merge conflicts arise from the rewritten
|
||||
squash ancestry, not from additional production changes on main.
|
||||
|
||||
Review and merge the final PR with **main** as its target and all four current-head
|
||||
checks green: pytest, pre-commit, Docker and CodeQL. Squash and merge is supported.
|
||||
Do not use a merge into the comparison branch as a release. Keep the original
|
||||
working copy and backup until manual installation acceptance is complete.
|
||||
|
||||
## Review and validation
|
||||
|
||||
- Optimize: preparation or conversion failure never returns a previous successful
|
||||
result; native result, generic solution and execution plan publish atomically.
|
||||
- Forecasts: provider power is converted from W to slot Wh exactly once. Raw missing
|
||||
records stay missing, control coverage is mandatory, and a shorter tail is clipped.
|
||||
- Economics: explicit/imported sale prices remain authoritative, including zero and
|
||||
negative values. Battery export is opt-in; terminal value is separate from LCOS.
|
||||
- Time: 15/60-minute slots, repeated DST hours, local-midnight forecast origins and
|
||||
non-integer timezone offsets are covered. Old GENETIC reports use saved timestamps.
|
||||
- Devices: EV deadlines, flexible power profiles, crossed per-cycle windows, completed
|
||||
cycles and minimum gaps are tested through the optimizer and result conversion.
|
||||
- Compatibility: GENETIC0 keeps its legacy request and device implementation. Both
|
||||
algorithms retain finite solution validity and existing persistent plan instructions.
|
||||
|
||||
Exact workflow results belong to each PR's current head; superseded green heads do
|
||||
not prove a later revision. The combined checks cover pinned mypy, generated OpenAPI
|
||||
and configuration, physics, native HTTP, automatic preparation, PDF generation and
|
||||
the 400-generation optimizer regression.
|
||||
|
||||
Local Windows server-PID tests and Docker builds have known environment failures
|
||||
that also reproduce on unchanged main. Linux CI remains the full-suite gate. Local
|
||||
PDF pixel comparison needs an optional converter; report semantics and PDF bytes
|
||||
are tested independently. Production HA/device behavior still needs manual acceptance.
|
||||
|
||||
## Preservation and release boundary
|
||||
|
||||
The original feature working copy is read-only. Its original HEAD and 102 saved files
|
||||
are checked against the private preservation manifest. Runtime configuration, secrets
|
||||
and real measurements are excluded from the PRs. No remote PR is merged and no HA
|
||||
configuration, production server or physical device is changed by this preparation.
|
||||
Reference in New Issue
Block a user