diff --git a/custom_components/octopus_energy/config/target_rates.py b/custom_components/octopus_energy/config/target_rates.py index 47dbc54d..90755618 100644 --- a/custom_components/octopus_energy/config/target_rates.py +++ b/custom_components/octopus_energy/config/target_rates.py @@ -147,10 +147,6 @@ def validate_target_rate_config(data, account_info, now): if data[CONFIG_TARGET_HOURS] % 0.5 != 0: errors[CONFIG_TARGET_HOURS] = "invalid_target_hours" - if CONFIG_TARGET_HOURS not in errors: - if data[CONFIG_TARGET_HOURS] < 0.5: - errors[CONFIG_TARGET_HOURS] = "invalid_target_hours" - if CONFIG_TARGET_START_TIME in data and data[CONFIG_TARGET_START_TIME] is not None: matches = re.search(REGEX_TIME, data[CONFIG_TARGET_START_TIME]) if matches is None: diff --git a/custom_components/octopus_energy/target_rates/__init__.py b/custom_components/octopus_energy/target_rates/__init__.py index ed14e3c3..7bf391c1 100644 --- a/custom_components/octopus_energy/target_rates/__init__.py +++ b/custom_components/octopus_energy/target_rates/__init__.py @@ -90,7 +90,7 @@ def calculate_continuous_times( max_rate = None, weighting: list = None ): - if (applicable_rates is None): + if (applicable_rates is None or target_hours <= 0): return [] applicable_rates.sort(key=__get_valid_to, reverse=find_last_rates) @@ -115,7 +115,7 @@ def calculate_continuous_times( continue continuous_rates = [rate] - continuous_rates_total = rate["value_inc_vat"] * (weighting[0] if weighting is not None else 1) + continuous_rates_total = rate["value_inc_vat"] * (weighting[0] if weighting is not None and len(weighting) > 0 else 1) for offset in range(1, total_required_rates): if (index + offset) < applicable_rates_count: diff --git a/custom_components/octopus_energy/translations/en.json b/custom_components/octopus_energy/translations/en.json index 59e7c88e..5f4ad701 100644 --- a/custom_components/octopus_energy/translations/en.json +++ b/custom_components/octopus_energy/translations/en.json @@ -69,7 +69,7 @@ "server_error": "Failed to connect to OE servers. Please try again later", "account_not_found": "Invalid API key or account id specified", "value_greater_than_zero": "Value must be greater or equal to 1", - "invalid_target_hours": "Target hours must be in half hour increments (e.g. 0.5 = 30 minutes; 1 = 60 minutes) and a minimum of 0.5.", + "invalid_target_hours": "Target hours must be in half hour increments (e.g. 0.5 = 30 minutes; 1 = 60 minutes).", "invalid_target_name": "Name must only include lower case alpha characters and underscore (e.g. my_target)", "invalid_target_time": "Must be in the format HH:MM", "invalid_offset": "Offset must be in the form of HH:MM:SS with an optional negative symbol", @@ -143,7 +143,7 @@ "server_error": "Failed to connect to OE servers. Please try again later", "account_not_found": "Invalid API key or account id specified", "value_greater_than_zero": "Value must be greater or equal to 1", - "invalid_target_hours": "Target hours must be in half hour increments (e.g. 0.5 = 30 minutes; 1 = 60 minutes) and a minimum of 0.5.", + "invalid_target_hours": "Target hours must be in half hour increments (e.g. 0.5 = 30 minutes; 1 = 60 minutes).", "invalid_target_time": "Must be in the format HH:MM", "invalid_offset": "Offset must be in the form of HH:MM:SS with an optional negative symbol", "invalid_hours_time_frame": "The target hours do not fit in the elected target time frame", diff --git a/tests/unit/config/test_validate_target_rate_config.py b/tests/unit/config/test_validate_target_rate_config.py index bbde0c90..fca38f3f 100644 --- a/tests/unit/config/test_validate_target_rate_config.py +++ b/tests/unit/config/test_validate_target_rate_config.py @@ -132,8 +132,39 @@ async def test_when_config_has_invalid_name_then_errors_returned(name, tariff): @pytest.mark.asyncio @pytest.mark.parametrize("hours,tariff",[ - ("", non_agile_tariff), ("0", non_agile_tariff), + ("0", agile_tariff), +]) +async def test_when_config_has_valid_hours_then_no_errors_returned(hours, tariff): + # Arrange + data = { + CONFIG_TARGET_TYPE: CONFIG_TARGET_TYPE_CONTINUOUS, + CONFIG_TARGET_NAME: "test", + CONFIG_TARGET_MPAN: mpan, + CONFIG_TARGET_HOURS: hours, + CONFIG_TARGET_START_TIME: "00:00", + CONFIG_TARGET_END_TIME: "16:00", + CONFIG_TARGET_OFFSET: "-00:00:00", + } + account_info = get_account_info(tariff) + + # Act + errors = validate_target_rate_config(data, account_info, now) + + # Assert + assert CONFIG_TARGET_HOURS not in errors + assert CONFIG_TARGET_NAME not in errors + assert CONFIG_TARGET_MPAN not in errors + assert CONFIG_TARGET_START_TIME not in errors + assert CONFIG_TARGET_END_TIME not in errors + assert CONFIG_TARGET_OFFSET not in errors + assert CONFIG_TARGET_MIN_RATE not in errors + assert CONFIG_TARGET_MAX_RATE not in errors + assert CONFIG_TARGET_WEIGHTING not in errors + +@pytest.mark.asyncio +@pytest.mark.parametrize("hours,tariff",[ + ("", non_agile_tariff), ("-1.0", non_agile_tariff), ("s", non_agile_tariff), ("1.01", non_agile_tariff), @@ -141,7 +172,6 @@ async def test_when_config_has_invalid_name_then_errors_returned(name, tariff): ("1.51", non_agile_tariff), ("1.99", non_agile_tariff), ("", agile_tariff), - ("0", agile_tariff), ("-1.0", agile_tariff), ("s", agile_tariff), ("1.01", agile_tariff), diff --git a/tests/unit/target_rates/test_calculate_continuous_times.py b/tests/unit/target_rates/test_calculate_continuous_times.py index e7785ff7..c5936e03 100644 --- a/tests/unit/target_rates/test_calculate_continuous_times.py +++ b/tests/unit/target_rates/test_calculate_continuous_times.py @@ -657,4 +657,43 @@ async def test_when_weighting_specified_then_result_is_adjusted(weighting: list, assert result[index]["start"] == expected_from expected_from = expected_from + timedelta(minutes=30) assert result[index]["end"] == expected_from - assert result[index]["value_inc_vat"] == expected_rates[index] \ No newline at end of file + assert result[index]["value_inc_vat"] == expected_rates[index] + +@pytest.mark.asyncio +@pytest.mark.parametrize("weighting",[ + (None), + ([]), +]) +async def test_when_target_hours_zero_then_result_is_adjusted(weighting): + # Arrange + current_date = datetime.strptime("2022-10-22T09:10:00+00:00", "%Y-%m-%dT%H:%M:%S%z") + target_start_time = "09:00" + target_end_time = "22:00" + + rates = create_rate_data( + datetime.strptime("2022-10-22T00:00:00+00:00", "%Y-%m-%dT%H:%M:%S%z"), + datetime.strptime("2022-10-23T00:00:00+00:00", "%Y-%m-%dT%H:%M:%S%z"), + [19.1, 18.9, 19.1, 15.1, 20] + ) + + applicable_rates = get_applicable_rates( + current_date, + target_start_time, + target_end_time, + rates, + True + ) + + # Act + result = calculate_continuous_times( + applicable_rates, + 0, + False, + False, + None, + weighting=weighting + ) + + # Assert + assert result is not None + assert len(result) == 0 \ No newline at end of file diff --git a/tests/unit/target_rates/test_create_weighting.py b/tests/unit/target_rates/test_create_weighting.py index 9987ad73..9293855e 100644 --- a/tests/unit/target_rates/test_create_weighting.py +++ b/tests/unit/target_rates/test_create_weighting.py @@ -7,6 +7,7 @@ (None, 3, [1,1,1]), ("", 3, [1,1,1]), (" ", 3, [1,1,1]), + ("", 0, []), ("1", 3, [1]), ("1,2,3", 3, [1,2,3]), ("2,*,3", 4, [2,1,1,3]),