Repository navigation
Commit dcc6017
fix(compare): stop the midnight tariff comparison changing the live plan's next decision (#5465)
* fix(compare): restore the plan in force's pre-clip copy after the tariff comparison
Plan selection scores the pre-clip version of each plan (#4403), keeping the plan in force's copy in plan_preclip
for the next re-plan to score as the previous plan. The tariff comparison runs calculate_plan() for every tariff,
each replacing plan_preclip with that tariff's 48-hour plan, and restored the windows and limits but not
plan_preclip. The first re-plan after the midnight comparison therefore scored the last tariff's plan as the plan
in force: on 9 Oct 2026 (Sigenergy, IOG) live scored its previous plan at 300.97p where the same plan scores 30.71p
without the comparison, and so switched plans regardless of metric_min_improvement_plan.
Found with the forward log replay (#5363): running the comparison inside the replay reproduced the inflated score,
and restoring each attribute the comparison changes, group by group, isolated plan_preclip. run_all() now saves and
restores it with the windows; a test runs run_all() with a tariff that replaces it and checks it comes back (it
fails without the fix).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* refactor(compare): save and restore a declared set of state, and plan each tariff from scratch
The comparison kept a hand-written list of attributes to save and restore, and plan_preclip leaked because it was
missing from it; end_record, the two rate_best_cost thresholds and plan_valid / plan_last_updated were missing too,
so after the comparison the next cycle published the last tariff's thresholds and treated the restored plan as
freshly computed. run_all() now saves and restores the attributes declared in COMPARE_PLAN_STATE,
COMPARE_HARDWARE_STATE (also reset after each tariff) and the rest of COMPARE_RESTORED_STATE, with the car state in
COMPARE_RESTORED_COPIES deep-copied as before.
Each tariff now plans from scratch (plan_valid False before its run): scored against the previous tariff's plan, the
keep-or-switch threshold in calculate_plan() could leave one tariff's result as another tariff's plan.
Tests: run_all() with a tariff run that changes every saved attribute must restore all of them, reset the hardware
values between tariffs and start each tariff with plan_valid False; and every attribute calculate_plan() assigns must
be either in COMPARE_PLAN_STATE or listed as rebuilt every run, so the next new piece of plan state fails a test
rather than leaking (checked: dropping end_record from the set fails it). T19 and T25 now check the declared sets
rather than the old source text.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix(compare): keep a re-plan requested during the comparison, and restore state even if the config restore raises
Two gaps a cold review found in the restore:
- Restoring plan_valid put back the True from before the comparison, overwriting a re-plan requested while it ran
(an HA event, the web UI or an agent tool changing a setting sets update_pending and clears plan_valid). The
next run would then treat the pre-change plan as valid. plan_valid is now restored as it was only if no re-plan
is pending.
- fetch_config_options() runs first in the final restore; if it raised, none of the saved state was put back -
the leak this branch fixes. The attribute restore now runs in a finally around the config restore, still last
so it wins.
The coverage check now reads calculate_plan() and every optimise pass with ast, so augmented, annotated and tuple
assignments to self are found too (nothing new is uncovered today). New tests: a re-plan requested during the
comparison leaves the plan invalid, and the plan is restored when the config restore raises; both fail without
this change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* test(compare): pin plan_valid and update_pending in the run_all() tests
run_all() now ends with plan_valid = saved and not update_pending. The
shared fixture starts with update_pending True and several earlier tests
leave plan_valid True, so test_run_all_restores_state failed or passed
depending on run order. Set a valid plan with no re-plan pending before
it, and save and restore both flags in it and in
test_run_all_restores_when_config_restore_raises, which left plan_valid
False for every later test.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: CI <ci@example.com>1 parent 9e5f002 commit dcc6017
2 files changed
Lines changed: 281 additions & 108 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
86 | 86 | | |
87 | 87 | | |
88 | 88 | | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
89 | 143 | | |
90 | 144 | | |
91 | 145 | | |
| |||
667 | 721 | | |
668 | 722 | | |
669 | 723 | | |
670 | | - | |
671 | | - | |
672 | | - | |
673 | | - | |
674 | | - | |
675 | | - | |
676 | | - | |
677 | | - | |
678 | | - | |
679 | | - | |
680 | | - | |
681 | | - | |
682 | | - | |
683 | | - | |
684 | | - | |
685 | | - | |
686 | | - | |
687 | | - | |
688 | | - | |
689 | | - | |
690 | | - | |
691 | | - | |
692 | | - | |
693 | | - | |
694 | | - | |
695 | | - | |
696 | | - | |
697 | | - | |
698 | | - | |
699 | | - | |
700 | | - | |
701 | | - | |
702 | | - | |
703 | | - | |
| 724 | + | |
| 725 | + | |
| 726 | + | |
704 | 727 | | |
705 | 728 | | |
706 | 729 | | |
| |||
748 | 771 | | |
749 | 772 | | |
750 | 773 | | |
| 774 | + | |
| 775 | + | |
| 776 | + | |
751 | 777 | | |
752 | | - | |
| 778 | + | |
753 | 779 | | |
754 | 780 | | |
755 | 781 | | |
756 | 782 | | |
757 | 783 | | |
758 | | - | |
759 | | - | |
760 | | - | |
761 | | - | |
762 | | - | |
763 | | - | |
| 784 | + | |
| 785 | + | |
764 | 786 | | |
765 | 787 | | |
766 | 788 | | |
| |||
776 | 798 | | |
777 | 799 | | |
778 | 800 | | |
779 | | - | |
780 | | - | |
781 | | - | |
782 | | - | |
783 | | - | |
784 | | - | |
785 | | - | |
786 | | - | |
787 | | - | |
788 | | - | |
789 | | - | |
790 | | - | |
791 | | - | |
792 | | - | |
793 | | - | |
794 | | - | |
795 | | - | |
796 | | - | |
797 | | - | |
798 | | - | |
799 | | - | |
800 | | - | |
801 | | - | |
802 | | - | |
803 | | - | |
804 | | - | |
805 | | - | |
806 | | - | |
807 | | - | |
808 | | - | |
809 | | - | |
810 | | - | |
811 | | - | |
812 | | - | |
813 | | - | |
814 | | - | |
815 | | - | |
816 | | - | |
817 | | - | |
818 | | - | |
819 | | - | |
820 | | - | |
821 | | - | |
822 | | - | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
0 commit comments