diff --git a/_docs/setup_target_rate.md b/_docs/setup_target_rate.md index f9298f7f..4d0aa3dd 100644 --- a/_docs/setup_target_rate.md +++ b/_docs/setup_target_rate.md @@ -1,11 +1,12 @@ # Setup Target Rate Sensor(s) - [Setup Target Rate Sensor(s)](#setup-target-rate-sensors) - - [From and To times](#from-and-to-times) + - [From/To Times](#fromto-times) - [Hours](#hours) - [Offset](#offset) - [Rolling Target](#rolling-target) - [Latest Period](#latest-period) + - [Invert Target Rates](#invert-target-rates) - [Attributes](#attributes) - [Examples](#examples) - [Continuous](#continuous) @@ -19,7 +20,7 @@ These sensors can then be used in automations to turn on/off devices that save y Each sensor will be in the form `binary_sensor.octopus_energy_target_{{TARGET_RATE_NAME}}`. -## From and To times +## From/To Times If you're wanting your devices to come on during a certain period, for example while you're at work, you can set the minimum and/or maximum times for your target rate sensor. These are specified in 24 hour clock format and will attempt to find the optimum discovered period during these times. @@ -53,6 +54,10 @@ For instance if you turn this on, the cheapest period is between `2023-01-01T00: This feature is toggled on by the `Find last applicable rates` checkbox. +## Invert Target Rates + +If this is checked, then the normal behaviour of the sensor will be revered. This means if you target an **import** sensor, it will normally look for the cheapest rates. But with this checked it will find the most expensive rates. Similarly if you target an **export** meter, normally it will look for the most expensive rates. But with this checked it will find the cheapest rates. + ## Attributes The following attributes are available on each sensor diff --git a/custom_components/octopus_energy/config_flow.py b/custom_components/octopus_energy/config_flow.py index 06aca296..7663e9e8 100644 --- a/custom_components/octopus_energy/config_flow.py +++ b/custom_components/octopus_energy/config_flow.py @@ -29,6 +29,7 @@ CONFIG_TARGET_OFFSET, CONFIG_TARGET_ROLLING_TARGET, CONFIG_TARGET_LAST_RATES, + CONFIG_TARGET_INVERT_TARGET_RATES, DATA_SCHEMA_ACCOUNT, DATA_CLIENT, @@ -149,6 +150,7 @@ async def async_setup_target_rate_schema(self): vol.Optional(CONFIG_TARGET_OFFSET): str, vol.Optional(CONFIG_TARGET_ROLLING_TARGET, default=False): bool, vol.Optional(CONFIG_TARGET_LAST_RATES, default=False): bool, + vol.Optional(CONFIG_TARGET_INVERT_TARGET_RATES, default=False): bool, }) async def async_step_target_rate(self, user_input): @@ -240,6 +242,14 @@ async def __async_setup_target_rate_schema(self, config, errors): find_last_rates = False if (CONFIG_TARGET_LAST_RATES in config): find_last_rates = config[CONFIG_TARGET_LAST_RATES] + + find_last_rates = False + if (CONFIG_TARGET_LAST_RATES in config): + find_last_rates = config[CONFIG_TARGET_LAST_RATES] + + invert_target_rates = False + if (CONFIG_TARGET_INVERT_TARGET_RATES in config): + invert_target_rates = config[CONFIG_TARGET_INVERT_TARGET_RATES] return self.async_show_form( step_id="target_rate", @@ -258,6 +268,7 @@ async def __async_setup_target_rate_schema(self, config, errors): offset_key: str, vol.Optional(CONFIG_TARGET_ROLLING_TARGET, default=is_rolling_target): bool, vol.Optional(CONFIG_TARGET_LAST_RATES, default=find_last_rates): bool, + vol.Optional(CONFIG_TARGET_INVERT_TARGET_RATES, default=invert_target_rates): bool, }), errors=errors ) diff --git a/custom_components/octopus_energy/const.py b/custom_components/octopus_energy/const.py index 7fe90879..97fc15a0 100644 --- a/custom_components/octopus_energy/const.py +++ b/custom_components/octopus_energy/const.py @@ -22,6 +22,7 @@ CONFIG_TARGET_OFFSET = "offset" CONFIG_TARGET_ROLLING_TARGET = "rolling_target" CONFIG_TARGET_LAST_RATES = "last_rates" +CONFIG_TARGET_INVERT_TARGET_RATES = "target_invert_target_rates" DATA_CONFIG = "CONFIG" DATA_ELECTRICITY_RATES_COORDINATOR = "ELECTRICITY_RATES_COORDINATOR" diff --git a/custom_components/octopus_energy/target_rates/target_rate.py b/custom_components/octopus_energy/target_rates/target_rate.py index 2120da63..de583603 100644 --- a/custom_components/octopus_energy/target_rates/target_rate.py +++ b/custom_components/octopus_energy/target_rates/target_rate.py @@ -14,8 +14,6 @@ BinarySensorEntity, ) from ..const import ( - CONFIG_TARGET_OFFSET, - CONFIG_TARGET_NAME, CONFIG_TARGET_HOURS, CONFIG_TARGET_TYPE, @@ -24,6 +22,8 @@ CONFIG_TARGET_MPAN, CONFIG_TARGET_ROLLING_TARGET, CONFIG_TARGET_LAST_RATES, + CONFIG_TARGET_INVERT_TARGET_RATES, + CONFIG_TARGET_OFFSET, REGEX_HOURS, REGEX_TIME, @@ -143,6 +143,12 @@ def is_on(self): target_hours = float(self._config[CONFIG_TARGET_HOURS]) + invert_target_rates = False + if (CONFIG_TARGET_INVERT_TARGET_RATES in self._config): + invert_target_rates = self._config[CONFIG_TARGET_INVERT_TARGET_RATES] + + find_highest_rates = (self._is_export and invert_target_rates == False) or (self._is_export == False and invert_target_rates) + if (self._config[CONFIG_TARGET_TYPE] == "Continuous"): self._target_rates = calculate_continuous_times( now(), @@ -151,7 +157,7 @@ def is_on(self): target_hours, all_rates, is_rolling_target, - self._is_export, + find_highest_rates, find_last_rates ) elif (self._config[CONFIG_TARGET_TYPE] == "Intermittent"): @@ -162,7 +168,7 @@ def is_on(self): target_hours, all_rates, is_rolling_target, - self._is_export, + find_highest_rates, find_last_rates ) else: diff --git a/custom_components/octopus_energy/translations/en.json b/custom_components/octopus_energy/translations/en.json index 953c37d1..f6844ae1 100644 --- a/custom_components/octopus_energy/translations/en.json +++ b/custom_components/octopus_energy/translations/en.json @@ -25,7 +25,8 @@ "End time": "The maximum time to stop the device", "offset": "The offset to apply to the scheduled block to be considered active", "rolling_target": "Re-evaluate multiple times a day", - "last_rates": "Find last applicable rates" + "last_rates": "Find last applicable rates", + "target_invert_target_rates": "Invert targeted rates" } } }, @@ -66,7 +67,8 @@ "End time": "The maximum time to stop the device", "offset": "The offset to apply to the scheduled block to be considered active", "rolling_target": "Re-evaluate multiple times a day", - "last_rates": "Find last applicable rates" + "last_rates": "Find last applicable rates", + "target_invert_target_rates": "Invert targeted rates" } } },