Implemented charge windows instead of just picking random low price s…#951
Implemented charge windows instead of just picking random low price s…#951
Conversation
…egments Signed-off-by: Fredrik Lidström <fredli74@gmail.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f4aff26557
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
This pull request implements a sophisticated charge window scheduling algorithm that replaces the simpler approach of just picking random low-price slots. The new system intelligently schedules charge windows by considering price data, time constraints, and multiple competing charge intents (manual, trip, routine, fill) to optimize both cost and charging behavior.
Changes:
- Replaced the old
GeneratePlanfunction with a new "soft intents" model that collects all charge requirements first, then schedules them optimally across available price windows - Implemented a greedy sliding-window algorithm to find optimal charge windows that minimize cost while respecting constraints like minimum window duration (to avoid fragmentation in cold weather) and maximum price thresholds
- Added support for splitting charge sessions across multiple windows when cost savings justify it, with configurable thresholds for when to split vs. consolidate charging
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Fredrik Lidström <fredli74@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 289a128246
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Fredrik Lidström <fredli74@gmail.com>
… quantumMs Signed-off-by: Fredrik Lidström <fredli74@gmail.com>
…ehicle not waking up to charge, cause it though the level was ok already Signed-off-by: Fredrik Lidström <fredli74@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Signed-off-by: Fredrik Lidström <fredli74@gmail.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 18 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| const locationSettings = this.getVehicleLocationSettings(vehicle, location_uuid); | ||
| const minimum_charge = locationSettings.directLevel; | ||
| const splitCharge = locationSettings.splitCharge || SplitCharge.Auto; |
| vehicleLog( | ||
| LogLevel.Trace, | ||
| vehicle.vehicle_uuid, | ||
| `scheduleWindows(${scheduleTag}): after step=${stepIndex + 1}/${atomicSteps.length} ` + | ||
| `${new Date(step.start).toISOString()}..${new Date(step.stop).toISOString()}@${fmtDbPrice(step.price)} ` + | ||
| `frontier=${frontierSummary(nextStates)} total=${countFrontierNodes(nextStates)} nodesRecorded=${nodesRecorded} ` + | ||
| `prunedDominated=${nodesPrunedDominated} prunedReplaced=${nodesPrunedReplaced}` | ||
| ); |
| @Field((_type) => String) | ||
| splitCharge!: SplitCharge | string; |
| export function vehicleLog(level: LogLevel, vehicleUUID: string, data: unknown) { | ||
| if (level <= LOGLEVEL) { | ||
| const msg = data instanceof Error ? data.message | ||
| : typeof data === "object" ? JSON.stringify(data) | ||
| : data; | ||
| const s = `${new Date().toISOString()} ${logSymbol[level]} ${vehicleUUID} ${msg}`; | ||
| switch (level) { | ||
| case LogLevel.Error: | ||
| case LogLevel.Warning: | ||
| console.error(s); | ||
| break; | ||
| case LogLevel.Info: | ||
| console.log(s); | ||
| break; | ||
| case LogLevel.Debug: | ||
| case LogLevel.Trace: | ||
| console.debug(s); | ||
| break; |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -85,6 +87,7 @@ | |||
| tile | |||
| @input="closedInfo" | |||
| > | |||
| <!-- eslint-disable-next-line vue/no-v-html --> | |||
| <span v-html="info.message"></span> | |||
| vehicleLog( | ||
| LogLevel.Trace, | ||
| vehicle.vehicle_uuid, | ||
| `scheduleWindows(${scheduleTag}): after step=${stepIndex + 1}/${atomicSteps.length} ` + | ||
| `${new Date(step.start).toISOString()}..${new Date(step.stop).toISOString()}@${fmtDbPrice(step.price)} ` + | ||
| `frontier=${frontierSummary(nextStates)} total=${countFrontierNodes(nextStates)} nodesRecorded=${nodesRecorded} ` + | ||
| `prunedDominated=${nodesPrunedDominated} prunedReplaced=${nodesPrunedReplaced}` | ||
| ); |
…interv�[6D�[K intervals
…ning U�[1D�[K UI feedback.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 22 out of 22 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return { | ||
| locationID: location_uuid, | ||
| directLevel: DEFAULT_DIRECTLEVEL, | ||
| goal: SmartChargeGoal.Balanced, | ||
| splitCharge: SplitCharge.Auto, | ||
| }; |
| @@ -90,18 +105,25 @@ | |||
|
|
|||
| saving!: { [key: string]: boolean }; | |||
| goalCBList!: { text: string; value: string }[]; | |||
| splitChargeList!: { text: string; value: string }[]; | |||
| data() { | |||
| return { | |||
| saving: { | |||
| directLevel: false, | |||
| goal: false, | |||
| splitCharge: false, | |||
| }, | |||
| goalCBList: [ | |||
| { text: "Low cost", value: SmartChargeGoal.Low }, | |||
| { text: "Balanced", value: SmartChargeGoal.Balanced }, | |||
| { text: "Full charge", value: SmartChargeGoal.Full }, | |||
| { text: "Custom", value: "%" }, | |||
| ], | |||
| splitChargeList: [ | |||
| { text: "Never", value: SplitCharge.Never }, | |||
| { text: "Auto", value: SplitCharge.Auto }, | |||
| { text: "Always", value: SplitCharge.Always }, | |||
| ], | |||
| get splitCharge(): string { | ||
| return this.settings.splitCharge || SplitCharge.Auto; | ||
| } |
| { | ||
| locationID: this.settings.locationID, | ||
| directLevel: this.settings.directLevel, | ||
| goal: goal.value || goal, | ||
| splitCharge: this.settings.splitCharge || SplitCharge.Auto, | ||
| } as GQLVehicleLocationSetting, |
| vehicleLog( | ||
| LogLevel.Trace, | ||
| vehicle.vehicle_uuid, | ||
| `scheduleWindows(${scheduleTag}): after step=${stepIndex + 1}/${atomicSteps.length} ` + | ||
| `${new Date(step.start).toISOString()}..${new Date(step.stop).toISOString()}@${fmtDbPrice(step.price)} ` + | ||
| `frontier=${frontierSummary(nextStates)} total=${countFrontierNodes(nextStates)} nodesRecorded=${nodesRecorded} ` + | ||
| `prunedDominated=${nodesPrunedDominated} prunedReplaced=${nodesPrunedReplaced}` | ||
| ); | ||
| states = nextStates; | ||
| } | ||
|
|
No description provided.