-
Notifications
You must be signed in to change notification settings - Fork 10
feat(mpc): run compiled Energyplan first in beta with Core DP shadow #1077
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
533179a
fix(mpc): replay every plan and represent a true zero PV cap
frahlg f4cc89f
fix(mpc): ignore sub-watt grid-limit residue
frahlg 1f00ebe
fix(mpc): replay Go DP from live SoC and clip at the operating band
frahlg e005853
feat(optimizer): bundle proprietary Energyplan worker
frahlg 0810d7b
Merge planning replay safety fixes for the Energyplan beta
frahlg 761dd6b
feat(mpc): run bundled Energyplan first in beta with Core DP shadow
frahlg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| --- | ||
| "ftw": minor | ||
| --- | ||
|
|
||
| Use the compiled Energyplan worker first in beta releases when no planner engine | ||
| is set. Core validates its plan, then runs Core DP as a background shadow on the | ||
| same downside PV input. Core DP remains the validated fallback, with a visible | ||
| reason when it takes over. The worker and its license ship and update with Core; | ||
| source stays private. Explicit core and python settings keep their roles. | ||
|
|
||
| Reject EV plans above the battery limit and clip DP power at the operating band | ||
| so fallback energy matches the power it schedules. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "ftw": patch | ||
| --- | ||
|
|
||
| Accept sub-watt solver residue at a slot's grid limit so an optimizer plan at the configured fuse ceiling does not trigger Go planner fallback. Larger import and export violations still fail validation. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "ftw": patch | ||
| --- | ||
|
|
||
| Go fallback plans are replayed against the same site-power and battery-energy identities as the mathematical optimizer before they can become the live plan. A true zero PV cap is now a distinct `pv_curtail_active` flag, so full curtailment is no longer serialized as “no cap”. A trajectory that cannot be reconstructed from the request is kept off dispatch. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| name: native energy worker | ||
|
|
||
| on: | ||
| pull_request: | ||
| paths: | ||
| - 'optimizer/native/**' | ||
| - 'go/internal/mpc/**' | ||
| - 'Makefile' | ||
| - '.github/workflows/native-solver.yml' | ||
| push: | ||
| branches: [master] | ||
| paths: | ||
| - 'optimizer/native/**' | ||
| - 'go/internal/mpc/**' | ||
| - 'Makefile' | ||
| - '.github/workflows/native-solver.yml' | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| native-solver: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v7 | ||
| - uses: actions/setup-go@v7 | ||
| with: | ||
| go-version: '1.26' | ||
| cache-dependency-path: go/go.sum | ||
| - name: Verify the binary bundle and Core integration | ||
| run: make native-solver-test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "os" | ||
| "path/filepath" | ||
| "runtime" | ||
| "strings" | ||
|
|
||
| "github.com/srcfl/ftw/go/internal/config" | ||
| ) | ||
|
|
||
| func plannerEngine(pl *config.Planner, version string) string { | ||
| if pl != nil && strings.TrimSpace(pl.Engine) != "" { | ||
| return pl.EngineName() | ||
| } | ||
| if base, valid := releaseVersionBase(version); valid && base != version && runtime.GOOS != "windows" { | ||
| return config.PlannerEngineEnergyplan | ||
| } | ||
| return config.PlannerEngineCore | ||
| } | ||
|
|
||
| func resolveEnergyplanBinary() string { | ||
| name := "ftw-solver-" + runtime.GOOS + "-" + runtime.GOARCH | ||
| candidates := []string{ | ||
| "optimizer/native/bundle/" + name, | ||
| "../optimizer/native/bundle/" + name, | ||
| } | ||
| if exe, err := os.Executable(); err == nil { | ||
| candidates = append([]string{filepath.Join(filepath.Dir(exe), "optimizer/native/bundle", name)}, candidates...) | ||
| } | ||
| for _, candidate := range candidates { | ||
| if st, err := os.Stat(candidate); err == nil && st.Mode().IsRegular() { | ||
| absolute, err := filepath.Abs(candidate) | ||
| if err == nil { | ||
| return absolute | ||
| } | ||
| } | ||
| } | ||
| // Keep an unavailable primary attached: its failure produces an explicit | ||
| // fallback reason instead of silently changing the configured engine. | ||
| return filepath.Join("/app/optimizer/native/bundle", name) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "runtime" | ||
| "testing" | ||
|
|
||
| "github.com/srcfl/ftw/go/internal/config" | ||
| ) | ||
|
|
||
| func TestEnergyplanBetaSelection(t *testing.T) { | ||
| for _, tc := range []struct{ version, engine, want string }{ | ||
| {"v2.15.0-beta.1", "", "energyplan"}, | ||
| {"v2.15.0", "", "core"}, | ||
| {"dev", "", "core"}, | ||
| {"dev-beta.invalid", "", "core"}, | ||
| {"v2.15.0-beta.1", "core", "core"}, | ||
| {"v2.15.0-beta.1", "python", "python"}, | ||
| {"dev", "Energyplan", "energyplan"}, | ||
| } { | ||
| if runtime.GOOS == "windows" && tc.engine == "" { | ||
| tc.want = "core" | ||
| } | ||
| if got := plannerEngine(&config.Planner{Engine: tc.engine}, tc.version); got != tc.want { | ||
| t.Errorf("%s / %q: got %s, want %s", tc.version, tc.engine, got, tc.want) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| func TestBuildMPCBetaStartsBundledEnergyplan(t *testing.T) { | ||
| if runtime.GOOS == "windows" { | ||
| t.Skip("no Windows worker") | ||
| } | ||
| old := Version | ||
| Version = "v2.15.0-beta.1" | ||
| t.Cleanup(func() { Version = old }) | ||
| // The old Python sidecar environment must not route Energyplan to it. | ||
| t.Setenv("FTW_OPTIMIZER_TRANSPORT", "unix") | ||
| t.Setenv("FTW_OPTIMIZER_SOCKET", "/missing/python.sock") | ||
| cfg, capacities := plannerEngineConfig(&config.Planner{Enabled: true}) | ||
| svc := buildMPC(cfg, nil, nil, capacities) | ||
| if svc == nil || !svc.OptimizerBundledWithCore() || svc.ShadowOptimizer != nil || svc.EnableRecourseShadow { | ||
| t.Fatalf("wrong beta wiring: %+v", svc) | ||
| } | ||
| t.Cleanup(func() { svc.Optimizer.Close() }) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Making
native-solver-testan unconditional dependency meansmake verifynow always runsverify.py, whosehost_key()rejects any host outside Linux amd64/arm64 and Darwin arm64 before the integrity-only checks can finish; Darwin amd64, Windows, and other development hosts therefore cannot run the project's standard verification even though the application deliberately falls back to Core there. Keep bundle checksum/unit checks universal, but conditionally skip the host handshake and native Go integration tests when no bundled executable matches the host.AGENTS.md reference: AGENTS.md:L114-L115
Useful? React with 👍 / 👎.