Skip to content

Commit

Permalink
feat(binary_sensor): Updated target rate sensors to be updatable
Browse files Browse the repository at this point in the history
  • Loading branch information
BottlecapDave committed May 1, 2022
1 parent a3830fc commit a6fbcca
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 28 deletions.
5 changes: 4 additions & 1 deletion custom_components/octopus_energy/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ async def async_setup_entry(hass, entry, async_add_entities):
return True

async def async_setup_target_sensors(hass, entry, async_add_entities):
config = entry.data
config = dict(entry.data)

if entry.options:
config.update(entry.options)

coordinator = hass.data[DOMAIN][DATA_ELECTRICITY_RATES_COORDINATOR]

Expand Down
109 changes: 82 additions & 27 deletions custom_components/octopus_energy/config_flow.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,36 @@

_LOGGER = logging.getLogger(__name__)

def validate_target_rate_sensor(data):
errors = {}

matches = re.search(REGEX_ENTITY_NAME, data[CONFIG_TARGET_NAME])
if matches == None:
errors[CONFIG_TARGET_NAME] = "invalid_target_name"

# For some reason float type isn't working properly - reporting user input malformed
matches = re.search(REGEX_HOURS, data[CONFIG_TARGET_HOURS])
if matches == None:
errors[CONFIG_TARGET_HOURS] = "invalid_target_hours"
else:
data[CONFIG_TARGET_HOURS] = float(data[CONFIG_TARGET_HOURS])
if data[CONFIG_TARGET_HOURS] % 0.5 != 0:
errors[CONFIG_TARGET_HOURS] = "invalid_target_hours"

if CONFIG_TARGET_START_TIME in data:
data[CONFIG_TARGET_START_TIME] = data[CONFIG_TARGET_START_TIME]
matches = re.search(REGEX_TIME, data[CONFIG_TARGET_START_TIME])
if matches == None:
errors[CONFIG_TARGET_START_TIME] = "invalid_target_time"

if CONFIG_TARGET_END_TIME in data:
data[CONFIG_TARGET_END_TIME] = data[CONFIG_TARGET_END_TIME]
matches = re.search(REGEX_TIME, data[CONFIG_TARGET_START_TIME])
if matches == None:
errors[CONFIG_TARGET_END_TIME] = "invalid_target_time"

return errors

class OctopusEnergyConfigFlow(ConfigFlow, domain=DOMAIN):
"""Config flow."""

Expand All @@ -62,7 +92,6 @@ async def async_setup_initial_account(self, user_input):
)

async def async_setup_target_rate_schema(self):
# test
client = self.hass.data[DOMAIN][DATA_CLIENT]
account_info = await client.async_get_account(self.hass.data[DOMAIN][DATA_ACCOUNT_ID])

Expand Down Expand Up @@ -90,32 +119,8 @@ async def async_setup_target_rate_schema(self):

async def async_step_target_rate(self, user_input):
"""Setup a target based on the provided user input"""
errors = {}

matches = re.search(REGEX_ENTITY_NAME, user_input[CONFIG_TARGET_NAME])
if matches == None:
errors[CONFIG_TARGET_NAME] = "invalid_target_name"

# For some reason float type isn't working properly - reporting user input malformed
matches = re.search(REGEX_HOURS, user_input[CONFIG_TARGET_HOURS])
if matches == None:
errors[CONFIG_TARGET_HOURS] = "invalid_target_hours"
else:
user_input[CONFIG_TARGET_HOURS] = float(user_input[CONFIG_TARGET_HOURS])
if user_input[CONFIG_TARGET_HOURS] % 0.5 != 0:
errors[CONFIG_TARGET_HOURS] = "invalid_target_hours"

if CONFIG_TARGET_START_TIME in user_input:
user_input[CONFIG_TARGET_START_TIME] = user_input[CONFIG_TARGET_START_TIME]
matches = re.search(REGEX_TIME, user_input[CONFIG_TARGET_START_TIME])
if matches == None:
errors[CONFIG_TARGET_START_TIME] = "invalid_target_time"

if CONFIG_TARGET_END_TIME in user_input:
user_input[CONFIG_TARGET_END_TIME] = user_input[CONFIG_TARGET_END_TIME]
matches = re.search(REGEX_TIME, user_input[CONFIG_TARGET_START_TIME])
if matches == None:
errors[CONFIG_TARGET_END_TIME] = "invalid_target_time"

errors = validate_target_rate_sensor(user_input)

if len(errors) < 1:
# Setup our targets sensor
Expand Down Expand Up @@ -169,6 +174,34 @@ class OptionsFlowHandler(OptionsFlow):
def __init__(self, entry) -> None:
self._entry = entry

async def __async_setup_target_rate_schema(self, config, errors):
client = self.hass.data[DOMAIN][DATA_CLIENT]
account_info = await client.async_get_account(self.hass.data[DOMAIN][DATA_ACCOUNT_ID])

meters = []
now = utcnow()
if len(account_info["electricity_meter_points"]) > 0:
for point in account_info["electricity_meter_points"]:
active_tariff_code = get_active_tariff_code(now, point["agreements"])
if active_tariff_code != None:
meters.append(point["mpan"])

if (CONFIG_TARGET_MPAN not in config):
config[CONFIG_TARGET_MPAN] = meters[0]

return self.async_show_form(
step_id="target_rate",
data_schema=vol.Schema({
vol.Required(CONFIG_TARGET_HOURS, default=f'{config[CONFIG_TARGET_HOURS]}'): str,
vol.Required(CONFIG_TARGET_MPAN, default=config[CONFIG_TARGET_MPAN]): vol.In(
meters
),
vol.Optional(CONFIG_TARGET_START_TIME, default=config[CONFIG_TARGET_START_TIME]): str,
vol.Optional(CONFIG_TARGET_END_TIME, default=config[CONFIG_TARGET_END_TIME]): str,
}),
errors=errors
)

async def async_step_init(self, user_input):
"""Manage the options for the custom component."""

Expand All @@ -187,6 +220,12 @@ async def async_step_init(self, user_input):
vol.Required(CONFIG_SMETS1, default=is_smets1): bool,
})
)
elif CONFIG_TARGET_TYPE in self._entry.data:
config = dict(self._entry.data)
if self._entry.options is not None:
config.update(self._entry.options)

return await self.__async_setup_target_rate_schema(config, {})

return self.async_abort(reason="not_supported")

Expand All @@ -198,4 +237,20 @@ async def async_step_user(self, user_input):
config.update(user_input)
return self.async_create_entry(title="", data=config)

return self.async_abort(reason="not_supported")

async def async_step_target_rate(self, user_input):
"""Manage the options for the custom component."""

if user_input is not None:
config = dict(self._entry.data)
config.update(user_input)

errors = validate_target_rate_sensor(config)

if (len(errors) > 0):
return await self.__async_setup_target_rate_schema(config, errors)

return self.async_create_entry(title="", data=config)

return self.async_abort(reason="not_supported")
10 changes: 10 additions & 0 deletions custom_components/octopus_energy/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,16 @@
"Api key": "Api key",
"SMETS1": "Is SMETS1 Gas Meter"
}
},
"target_rate": {
"title": "Update Target Rate",
"description": "Update the settings for your target rate sensor, which can be used to help you save energy and money.",
"data": {
"Hours": "The hours you require.",
"MPAN": "The MPAN number of the meter to apply the target to",
"Start time": "The minimum time to start the device",
"End time": "The maximum time to stop the device"
}
}
},
"error": {
Expand Down

0 comments on commit a6fbcca

Please sign in to comment.