Skip to content

Commit f7e268e

Browse files
refactor(compare): record which rate sides a tariff replaced explicitly (#5163 review)
fetch_rates() decided whether a tariff had installed its own rates by comparing the rate table against the deepcopy it started from. That held only because every rate source assigns a fresh dict and nothing copies the table in between. Each branch that installs a tariff's own rates now sets import_replaced/export_replaced, and both the #5286 dispatch-marker restore and the saving-minute clearing read those flags. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 7f018f0 commit f7e268e

1 file changed

Lines changed: 18 additions & 6 deletions

File tree

‎apps/predbat/compare.py‎

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,11 @@ def fetch_rates(self, tariff, rate_import_base, rate_export_base, io_adjusted_ba
7373
# Reset rates to base
7474
pb.rate_import = copy.deepcopy(rate_import_base)
7575
pb.rate_export = copy.deepcopy(rate_export_base)
76-
# Both sides start as the live cycle's rates; fetch_rates() below replaces a side only if this tariff supplies it
77-
live_import = pb.rate_import
78-
live_export = pb.rate_export
76+
# Both sides start as the live cycle's rates. Each branch below that installs this tariff's own
77+
# rates for a side records it here, so the checks further down don't depend on object identity
78+
# (which a copying rate_replicate() or rate source would silently break)
79+
import_replaced = False
80+
export_replaced = False
7981

8082
# Intelligent Octopus dispatch markers go with the import rates they came from (#5286)
8183
pb.io_adjusted = {}
@@ -94,18 +96,21 @@ def fetch_rates(self, tariff, rate_import_base, rate_export_base, io_adjusted_ba
9496
# Fixed URL for rate import
9597
import_url = pb.resolve_arg("rates_import_octopus_url", tariff["rates_import_octopus_url"], indirect=False)
9698
pb.rate_import = pb.download_octopus_rates(import_url)
99+
import_replaced = True
97100
elif "metric_octopus_import" in tariff:
98101
# Octopus import rates
99102
entity_id = pb.resolve_arg("metric_octopus_import", tariff["metric_octopus_import"], indirect=False)
100103
if entity_id:
101104
pb.rate_import = pb.fetch_octopus_rates(entity_id, adjust_key="is_intelligent_adjusted")
105+
import_replaced = True
102106
else:
103107
self.log("Warn: Compare tariff {} bad Octopus entity id {}".format(tariff.get("id", ""), entity_id))
104108
elif "metric_energidataservice_import" in tariff:
105109
# Energi Data Service import rates
106110
entity_id = pb.resolve_arg("metric_energidataservice_import", tariff["metric_energidataservice_import"], indirect=False)
107111
if entity_id:
108112
pb.rate_import = pb.fetch_energidataservice_rates(entity_id, adjust_key="is_intelligent_adjusted")
113+
import_replaced = True
109114
else:
110115
self.log("Warn: Compare tariff {} bad Energidata entity id {}".format(tariff.get("id", ""), entity_id))
111116
elif "metric_stromligning_import_today" in tariff or "metric_stromligning_import_tomorrow" in tariff:
@@ -114,30 +119,35 @@ def fetch_rates(self, tariff, rate_import_base, rate_export_base, io_adjusted_ba
114119
entity_id_tomorrow = pb.resolve_arg("metric_stromligning_import_tomorrow", tariff.get("metric_stromligning_import_tomorrow"))
115120
if entity_id_today or entity_id_tomorrow:
116121
pb.rate_import = pb.fetch_stromligning_rates(entity_id_today, entity_id_tomorrow, adjust_key="is_intelligent_adjusted")
122+
import_replaced = True
117123
else:
118124
self.log("Warn: Compare tariff {} bad Strømligning entity ids".format(tariff.get("id", "")))
119125
elif "rates_import" in tariff:
120126
pb.rate_import = pb.basic_rates(tariff["rates_import"], "rates_import", include_manual_api=False)
127+
import_replaced = True
121128
else:
122129
self.log("Using existing rate import data")
123-
if pb.rate_import is live_import:
130+
if not import_replaced:
124131
pb.io_adjusted = copy.deepcopy(io_adjusted_base)
125132

126133
if "rates_export_octopus_url" in tariff:
127134
# Fixed URL for rate export
128135
pb.rate_export = pb.download_octopus_rates(pb.resolve_arg("rates_export_octopus_url", tariff["rates_export_octopus_url"], indirect=False))
136+
export_replaced = True
129137
elif "metric_octopus_export" in tariff:
130138
# Octopus export rates
131139
entity_id = pb.resolve_arg("metric_octopus_export", tariff["metric_octopus_export"], indirect=False)
132140
if entity_id:
133141
pb.rate_export = pb.fetch_octopus_rates(entity_id)
142+
export_replaced = True
134143
else:
135144
self.log("Warn: Compare tariff {} bad Octopus entity id {}".format(tariff.get("id", ""), entity_id))
136145
elif "metric_energidataservice_export" in tariff:
137146
# Energi Data Service export rates
138147
entity_id = pb.resolve_arg("metric_energidataservice_export", tariff["metric_energidataservice_export"], indirect=False)
139148
if entity_id:
140149
pb.rate_export = pb.fetch_energidataservice_rates(entity_id, adjust_key="is_intelligent_adjusted")
150+
export_replaced = True
141151
else:
142152
self.log("Warn: Compare tariff {} bad Energidata entity id {}".format(tariff.get("id", ""), entity_id))
143153
elif "metric_stromligning_export_today" in tariff or "metric_stromligning_export_tomorrow" in tariff:
@@ -146,20 +156,22 @@ def fetch_rates(self, tariff, rate_import_base, rate_export_base, io_adjusted_ba
146156
entity_id_tomorrow = pb.resolve_arg("metric_stromligning_export_tomorrow", tariff.get("metric_stromligning_export_tomorrow"))
147157
if entity_id_today or entity_id_tomorrow:
148158
pb.rate_export = pb.fetch_stromligning_rates(entity_id_today, entity_id_tomorrow)
159+
export_replaced = True
149160
else:
150161
self.log("Warn: Compare tariff {} bad Strømligning entity ids".format(tariff.get("id", "")))
151162
elif "rates_export" in tariff:
152163
pb.rate_export = pb.basic_rates(tariff["rates_export"], "rates_export", include_manual_api=False)
164+
export_replaced = True
153165
else:
154166
self.log("Using existing rate export data")
155167

156168
# A tariff that supplied its own rates for a side makes the live saving minutes for that side
157169
# stale: they are offsets into the live tables, and would map unrelated minutes of the new tariff
158170
# back to live "base" rates. A side left on the live rates keeps them.
159-
if pb.rate_import is not live_import:
171+
if import_replaced:
160172
pb.rate_import_saving_minutes = set()
161173
pb.rate_import_pre_saving = {}
162-
if pb.rate_export is not live_export:
174+
if export_replaced:
163175
pb.rate_export_saving_minutes = set()
164176
pb.rate_export_pre_saving = {}
165177

0 commit comments

Comments
 (0)