Skip to content

Commit 713545b

Browse files
Octopus intelligent detection fix (#4204)
1 parent 3cd41cd commit 713545b

3 files changed

Lines changed: 55 additions & 3 deletions

File tree

apps/predbat/octopus.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ async def async_update_intelligent_devices(self, account_id):
683683
"""
684684
import_tariff = self.tariffs.get("import", {})
685685
tariffCode = import_tariff.get("tariffCode", "")
686-
if "INTELLI-" not in tariffCode:
686+
if not self.is_intelligent_go_tariff(tariffCode):
687687
return
688688
deviceID = import_tariff.get("deviceID", None)
689689
if deviceID:
@@ -1217,6 +1217,16 @@ def _get_rate_for_time(self, rates_list, timestamp, now=None):
12171217
best_rate = rate.get("value_inc_vat", None)
12181218
return best_rate
12191219

1220+
@staticmethod
1221+
def is_intelligent_go_tariff(tariff_code):
1222+
"""
1223+
Determine whether a tariff code is an Intelligent GO (IOG) tariff.
1224+
"""
1225+
if not tariff_code:
1226+
return False
1227+
else:
1228+
return ("INTELLI-" in tariff_code) or ("IOG-" in tariff_code)
1229+
12201230
async def async_get_day_night_rates(self, url, product_code="", tariff_code=""):
12211231
"""
12221232
Get day and night rates from Octopus.
@@ -1235,7 +1245,7 @@ async def async_get_day_night_rates(self, url, product_code="", tariff_code=""):
12351245
self.log("Info: OctopusAPI: Day rate entries: {} night rate entries: {}".format(len(result_day) if result_day else 0, len(result_night) if result_night else 0))
12361246
if result_day and result_night:
12371247
# Select night window based on tariff type
1238-
if ("INTELLI" in tariff_code) or ("IOG-" in tariff_code):
1248+
if self.is_intelligent_go_tariff(tariff_code):
12391249
window = OCTOPUS_NIGHT_RATE_WINDOWS["iog"]
12401250
elif tariff_code and "GO-" in tariff_code:
12411251
window = OCTOPUS_NIGHT_RATE_WINDOWS["go"]

apps/predbat/predbat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
import pytz
3636
import asyncio
3737

38-
THIS_VERSION = "v8.44.5"
38+
THIS_VERSION = "v8.44.6"
3939

4040
from download import predbat_update_move, predbat_update_download, check_install, DEFAULT_PREDBAT_REPOSITORY
4141
from const import MINUTE_WATT

apps/predbat/tests/test_octopus_day_night_rates.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,48 @@ async def mock_fetch7(url, **kwargs):
368368
else:
369369
print("PASS: None returned when timestamp falls exactly on valid_to boundary")
370370

371+
# ------------------------------------------------------------------
372+
# Test 9: is_intelligent_go_tariff — shared IOG/Intelligent detection helper.
373+
# Covers the bug where async_update_intelligent_devices only checked for
374+
# "INTELLI-" and missed plain "IOG-" tariff codes.
375+
# ------------------------------------------------------------------
376+
print("\n*** Test 9: is_intelligent_go_tariff detects INTELLI and IOG- tariff codes ***")
377+
intelligent_go_cases = [
378+
("E-1R-INTELLI-VAR-25-01-01-H", True),
379+
("E-1R-IOG-SMB-TOU-25-12-12-H", True),
380+
("E-1R-INTELLI-FLUX-IMPORT-23-07-14-A", True),
381+
("E-1R-GO-VAR-22-10-14-H", False),
382+
("E-2R-VAR-22-11-01-A", False),
383+
("", False),
384+
]
385+
case_failed = False
386+
for tariff_code, expected in intelligent_go_cases:
387+
actual = OctopusAPI.is_intelligent_go_tariff(tariff_code)
388+
if actual != expected:
389+
print(f"ERROR: is_intelligent_go_tariff({tariff_code!r}) returned {actual}, expected {expected}")
390+
failed = True
391+
case_failed = True
392+
if not case_failed:
393+
print("PASS: is_intelligent_go_tariff correctly classifies INTELLI, IOG-, and non-intelligent tariff codes")
394+
395+
# ------------------------------------------------------------------
396+
# Test 10: async_update_intelligent_devices regression — an IOG-only tariff
397+
# code (no "INTELLI" substring) must still be treated as an intelligent
398+
# tariff and proceed to fetch devices, rather than returning early.
399+
# ------------------------------------------------------------------
400+
print("\n*** Test 10: async_update_intelligent_devices proceeds for IOG-only tariff code ***")
401+
api10 = OctopusAPI(my_predbat, key="test-key", account_id="test-account", automatic=False)
402+
api10.tariffs = {"import": {"tariffCode": "E-1R-IOG-SMB-TOU-25-12-12-H", "deviceID": "test-device-789"}}
403+
api10.async_get_intelligent_devices = AsyncMock(return_value={})
404+
405+
await api10.async_update_intelligent_devices("test-account")
406+
407+
if api10.async_get_intelligent_devices.call_count != 1:
408+
print(f"ERROR: Expected async_get_intelligent_devices to be called for IOG-only tariff code, got {api10.async_get_intelligent_devices.call_count} calls")
409+
failed = True
410+
else:
411+
print("PASS: async_update_intelligent_devices proceeds for IOG-only tariff code (no INTELLI substring)")
412+
371413
# ------------------------------------------------------------------
372414
if failed:
373415
print("\n**** ❌ async_get_day_night_rates tests FAILED ****")

0 commit comments

Comments
 (0)