Repository navigation
Commit 7cad36e
Don't trust Intelligent slots the car won't need (consider_full) (#5403)
* feat(octopus): don't trust Intelligent slots the car won't need (#4482)
With octopus_intelligent_consider_full on, load_octopus_slots() already ends
each car's slots where it reaches its limit, so the car is modelled not to
draw in the rest - but every dispatch minute still kept its cheap rate, and
the house battery planned around slots Octopus only bills cheap when the car
charges in them.
octopus_surplus_minutes() works out the future dispatch minutes no car still
needs (rounded out to whole half hours, shared across cars, outside the fixed
23:30-05:30 window), and both rate paths now withhold them the way they
already do for a cancelled car: rate_add_io_slots() doesn't stamp them, and
dynamic_load_car_strip_feed_rates() removes a discount the rate feed already
delivered. Elapsed minutes keep their rate so today's cost stays true.
Behaviour is unchanged with consider_full off.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(octopus): a cancelled car's slots still count as needed by the car-need gate
dynamic_load_car_check() cancels a car by zeroing its future slots and keeping
the kWh in kwh_cancelled. The car-need gate read that zero as "the car won't
need it", so with octopus_intelligent_consider_full on it stripped the cheap
rate from the rest of the half hour #5229 deliberately keeps for a car seen
charging in it. Cancellation decides a cancelled car's rate itself; the gate
now only answers whether a slot is beyond the car's need.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(octopus): keep the current half hour out of the car-need gate
The surplus started at minutes_now, which usually falls mid-period, so the rest
of the current half hour lost its low rate once the car was full - even when
the car charged earlier in it, which makes Octopus bill the whole period cheap.
Surplus now starts at the next half-hour boundary. Clamping back to the start
of the current period instead would have marked elapsed minutes as surplus too,
and rate_add_io_slots() applies the skip to past minutes, misreporting today's
cost.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(octopus): decide the car-need gate per car before sharing (#5403 review)
Copilot's review of the gate found four ways it could misprice a dispatch:
- The surplus started at the next half-hour boundary computed as a ceiling,
which is the current boundary when the floored clock sits on one (a fetch at
14:02 reads 14:00), so the current half hour could still lose its rate. It now
starts at the strictly next boundary.
- A cancelled car's kwh_cancelled counted as needed for the whole slot, so it
kept a full car's surplus minutes cheap though neither car would charge then.
A car's need now counts only before its own cheap rate ends
(dynamic_load_car_strip_from()), which still keeps the half hour GH#5316
keeps for a car seen charging in it.
- A car not modelled from its Octopus slots was simply skipped, so a full car's
overlapping surplus stripped its discount too. Its dispatches are now kept,
up to its own strip_from.
- An untrimmed dispatch in progress (octopus_intelligent_slot isn't trimmed to
now, unlike the Octopus API component's) is capped from its original start,
so the capped slot can end before the car finishes. The running dispatch is
now left alone; dynamic load cancels it in real time once the car stops.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(octopus): judge a running dispatch from now, and replan when the surplus changes (#5403 review)
Trefor's review of #5403:
1. A dispatch in progress was exempt from the gate for its whole length, so
one long dispatch kept all its surplus cheap from the moment it started,
while the same charge chunked into half-hour dispatches didn't. With
consider_full on, load_octopus_slots() now caps a running dispatch's need
from its remaining span and energy (as trim_started_dispatch() already does
for the Octopus API component, but octopus_intelligent_slot doesn't), after
the slot-cap chunking, which still counts it from its real start. The
exemption is gone.
2. A change in the surplus didn't force a replan - the rates can move without
the slots moving, as the car's SoC changes how many half hours it needs.
fetch_sensor_data() now replans when it changes, guarded by save like
dynamic_load_car_check(). Only the part of the previous surplus still ahead
is compared, so time passing alone isn't a change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>1 parent c246275 commit 7cad36e
6 files changed
Lines changed: 420 additions & 10 deletions
File tree
- apps/predbat
- tests
- docs
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1188 | 1188 | | |
1189 | 1189 | | |
1190 | 1190 | | |
| 1191 | + | |
1191 | 1192 | | |
1192 | 1193 | | |
1193 | 1194 | | |
| |||
1241 | 1242 | | |
1242 | 1243 | | |
1243 | 1244 | | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
1244 | 1251 | | |
1245 | 1252 | | |
1246 | 1253 | | |
| |||
1374 | 1381 | | |
1375 | 1382 | | |
1376 | 1383 | | |
1377 | | - | |
| 1384 | + | |
1378 | 1385 | | |
1379 | 1386 | | |
1380 | 1387 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3742 | 3742 | | |
3743 | 3743 | | |
3744 | 3744 | | |
| 3745 | + | |
| 3746 | + | |
| 3747 | + | |
| 3748 | + | |
| 3749 | + | |
| 3750 | + | |
| 3751 | + | |
| 3752 | + | |
3745 | 3753 | | |
3746 | 3754 | | |
3747 | 3755 | | |
| |||
3854 | 3862 | | |
3855 | 3863 | | |
3856 | 3864 | | |
| 3865 | + | |
| 3866 | + | |
| 3867 | + | |
3857 | 3868 | | |
3858 | 3869 | | |
3859 | 3870 | | |
| |||
3915 | 3926 | | |
3916 | 3927 | | |
3917 | 3928 | | |
| 3929 | + | |
| 3930 | + | |
| 3931 | + | |
| 3932 | + | |
| 3933 | + | |
| 3934 | + | |
| 3935 | + | |
| 3936 | + | |
| 3937 | + | |
| 3938 | + | |
| 3939 | + | |
| 3940 | + | |
| 3941 | + | |
| 3942 | + | |
| 3943 | + | |
| 3944 | + | |
| 3945 | + | |
| 3946 | + | |
| 3947 | + | |
| 3948 | + | |
| 3949 | + | |
| 3950 | + | |
| 3951 | + | |
| 3952 | + | |
| 3953 | + | |
| 3954 | + | |
| 3955 | + | |
| 3956 | + | |
| 3957 | + | |
| 3958 | + | |
| 3959 | + | |
| 3960 | + | |
| 3961 | + | |
| 3962 | + | |
| 3963 | + | |
| 3964 | + | |
| 3965 | + | |
| 3966 | + | |
| 3967 | + | |
| 3968 | + | |
| 3969 | + | |
| 3970 | + | |
| 3971 | + | |
| 3972 | + | |
| 3973 | + | |
| 3974 | + | |
| 3975 | + | |
| 3976 | + | |
| 3977 | + | |
| 3978 | + | |
| 3979 | + | |
| 3980 | + | |
| 3981 | + | |
| 3982 | + | |
| 3983 | + | |
| 3984 | + | |
| 3985 | + | |
| 3986 | + | |
| 3987 | + | |
| 3988 | + | |
| 3989 | + | |
| 3990 | + | |
| 3991 | + | |
| 3992 | + | |
| 3993 | + | |
| 3994 | + | |
| 3995 | + | |
| 3996 | + | |
3918 | 3997 | | |
3919 | 3998 | | |
3920 | 3999 | | |
| |||
3932 | 4011 | | |
3933 | 4012 | | |
3934 | 4013 | | |
3935 | | - | |
| 4014 | + | |
3936 | 4015 | | |
3937 | 4016 | | |
3938 | 4017 | | |
| |||
3954 | 4033 | | |
3955 | 4034 | | |
3956 | 4035 | | |
3957 | | - | |
3958 | | - | |
3959 | | - | |
3960 | 4036 | | |
3961 | | - | |
| 4037 | + | |
| 4038 | + | |
3962 | 4039 | | |
3963 | 4040 | | |
3964 | | - | |
3965 | | - | |
| 4041 | + | |
3966 | 4042 | | |
3967 | 4043 | | |
3968 | 4044 | | |
3969 | 4045 | | |
| 4046 | + | |
| 4047 | + | |
3970 | 4048 | | |
3971 | 4049 | | |
3972 | 4050 | | |
3973 | | - | |
| 4051 | + | |
3974 | 4052 | | |
3975 | 4053 | | |
3976 | 4054 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
560 | 560 | | |
561 | 561 | | |
562 | 562 | | |
| 563 | + | |
563 | 564 | | |
564 | 565 | | |
565 | 566 | | |
| |||
0 commit comments