diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 000000000..e69826427 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,8 @@ +{ + "permissions": { + "allow": [ + "Bash(git -C /Users/treforsouthwell/source/batpred diff HEAD -- apps/predbat/predbat.py)", + "Bash(python3 -c ' *)" + ] + } +} diff --git a/apps/predbat/gecloud.py b/apps/predbat/gecloud.py index 0ab287481..b4ce3e640 100644 --- a/apps/predbat/gecloud.py +++ b/apps/predbat/gecloud.py @@ -604,6 +604,8 @@ async def publish_meter(self, device, meter): self.dashboard_item(entity_name + "_grid_export_total", state=meter[key][subkey].get("export", 0), attributes=attribute_table.get("grid_export_total", {}), app="gecloud") async def enable_default_options(self, device, registers): + """Enable default options for the device.""" + changed = False for key in registers: reg_name = registers[key].get("name", "") value = registers[key].get("value", None) @@ -616,10 +618,9 @@ async def enable_default_options(self, device, registers): if result and ("value" in result): registers[key]["value"] = result["value"] await self.publish_registers(device, self.settings[device], select_key=key) - return True + changed = True else: self.log("GECloud: Warn: Failed to set {} for {}".format(ha_name, device)) - return False if ("inverter_max_output_active_power_percent" in ha_name) or ("ac_charge_upper_percent_limit" in ha_name) or ("_upper_soc_percent_limit" in ha_name): if "enable_" in ha_name: continue @@ -630,10 +631,9 @@ async def enable_default_options(self, device, registers): if result and ("value" in result): registers[key]["value"] = result["value"] await self.publish_registers(device, self.settings[device], select_key=key) - return True + changed = True else: self.log("GECloud: Warn: Failed to set {} for {}".format(ha_name, device)) - return False if "charge_up_to_percent" in ha_name: if not value or value < 100: self.log("GECloud: Setting {} to 100% for {}, previous value was {}".format(ha_name, device, value)) @@ -641,10 +641,9 @@ async def enable_default_options(self, device, registers): if result and ("value" in result): registers[key]["value"] = result["value"] await self.publish_registers(device, self.settings[device], select_key=key) - return True + changed = True else: self.log("GECloud: Warn: Failed to set {} for {}".format(ha_name, device)) - return False if "discharge_down_to_percent" in ha_name: if not value or value > 4: self.log("GECloud: Setting {} to 4% for {}, previous value was {}".format(ha_name, device, value)) @@ -652,10 +651,9 @@ async def enable_default_options(self, device, registers): if result and ("value" in result): registers[key]["value"] = result["value"] await self.publish_registers(device, self.settings[device], select_key=key) - return True + changed = True else: self.log("GECloud: Warn: Failed to set {} for {}".format(ha_name, device)) - return False # Reset AC charge start and end times to 00:00 to disable for charge_id in range(2, 11): if ( @@ -670,25 +668,24 @@ async def enable_default_options(self, device, registers): if result and ("value" in result): registers[key]["value"] = result["value"] await self.publish_registers(device, self.settings[device], select_key=key) - return True + changed = True else: self.log("GECloud: Warn: Failed to set {} for {}".format(ha_name, device)) - return False if "real_time_control" in ha_name: if value: self.log("GECloud: Real-time control already enabled for {}".format(device)) - return True + changed = True + continue else: self.log("GECloud: Enabling real-time control for {} as current value is {}".format(device, value)) result = await self.async_write_inverter_setting(device, key, True) if result and ("value" in result): registers[key]["value"] = result["value"] await self.publish_registers(device, self.settings[device], select_key=key) - return True + changed = True else: self.log("GECloud: Warn: Failed to enable real-time control for {}".format(device)) - return False - return False + return changed async def publish_registers(self, device, registers, select_key=None): """ diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index ebb3ded37..25a81e35a 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -36,7 +36,7 @@ import requests import asyncio -THIS_VERSION = "v8.40.10" +THIS_VERSION = "v8.40.11" from download import predbat_update_move, predbat_update_download, check_install, resolve_predbat_repository, DEFAULT_PREDBAT_REPOSITORY from const import MINUTE_WATT diff --git a/apps/predbat/tests/test_ge_cloud.py b/apps/predbat/tests/test_ge_cloud.py index f89d5ce9b..573911eae 100644 --- a/apps/predbat/tests/test_ge_cloud.py +++ b/apps/predbat/tests/test_ge_cloud.py @@ -3401,7 +3401,7 @@ async def mock_write_fail(device, key, value): print("ERROR: enable_default_options should return False when write fails") return 1 - # Test 10: Multiple settings - should process first match only + # Test 10: Multiple settings - should process all matching settings write_calls = [] registers = {100: {"name": "Export_SOC_Percent_Limit", "value": 10, "validation_rules": []}, 102: {"name": "AC_Charge_Upper_Percent_Limit", "value": 80, "validation_rules": []}} @@ -3410,14 +3410,11 @@ async def mock_write_fail(device, key, value): result = await ge_cloud.enable_default_options("test123", registers) if not result: - print("ERROR: enable_default_options should return True after processing first match") + print("ERROR: enable_default_options should return True after processing all matches") return 1 - # Should only process the first matching setting (export SOC limit) - if len(write_calls) != 1: - print("ERROR: Should only process first matching setting, got {} calls".format(len(write_calls))) - return 1 - if write_calls[0]["key"] != 100: - print("ERROR: Should process first setting (key 100), got key {}".format(write_calls[0]["key"])) + # Should process all matching settings + if len(write_calls) != 2: + print("ERROR: Should process all matching settings, got {} calls".format(len(write_calls))) return 1 # Test 11: AC charge slot 2 start time needs resetting