Skip to content

Commit

Permalink
add reconfiguration flow
Browse files Browse the repository at this point in the history
  • Loading branch information
bj00rn committed Oct 30, 2024
1 parent 4df5055 commit ec3b21a
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 30 deletions.
99 changes: 73 additions & 26 deletions custom_components/nordpool/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
"""Adds config flow for nordpool."""
import logging
import re
from typing import TYPE_CHECKING

import voluptuous as vol
from homeassistant import config_entries
from homeassistant.helpers.template import Template

if TYPE_CHECKING:
from typing import Any, Mapping

from . import DOMAIN
from .sensor import _PRICE_IN, _REGIONS, DEFAULT_TEMPLATE

Expand All @@ -24,6 +28,7 @@ class NordpoolFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
def __init__(self):
"""Initialize."""
self._errors = {}
_config_entry = None

async def async_step_user(
self, user_input=None
Expand All @@ -33,47 +38,89 @@ async def async_step_user(

if user_input is not None:
template_ok = False
if user_input["additional_costs"] in (None, ""):
user_input["additional_costs"] = DEFAULT_TEMPLATE
self._patch_template(user_input["additional_costs"])

template_ok = await self._valid_template(user_input["additional_costs"])
if template_ok:
return self.async_create_entry(title="Nordpool", data=user_input)
else:
# Lets try to remove the most common mistakes, this will still fail if the template
# was writte in notepad or something like that..
user_input["additional_costs"] = re.sub(
r"\s{2,}", "", user_input["additional_costs"]
)
self._errors["base"] = "invalid_template"

return self.async_show_form(
step_id="user",
**self._get_form_data(user_input),
errors=self._errors,
)

async def async_step_reconfigure(
self, entry_data: "Mapping[str, Any]"
) -> config_entries.ConfigFlowResult:
"""Handle a reconfiguration flow initialized by the user."""
config_entry = self.hass.config_entries.async_get_entry(
self.context["entry_id"]
)
self._config_entry = config_entry
return await self.async_step_reconfigure_confirm()

async def async_step_reconfigure_confirm(
self, user_input: "dict[str, Any] | None" = None
) -> config_entries.ConfigFlowResult:
"""Handle a reconfiguration flow initialized by the user."""

if user_input is not None:
template_ok = False
self._patch_template(user_input["additional_costs"])

template_ok = await self._valid_template(user_input["additional_costs"])
if template_ok:
return self.async_create_entry(title="Nordpool", data=user_input)
else:
self._errors["base"] = "invalid_template"

data_schema = {
vol.Required("region", default=None): vol.In(regions),
vol.Optional("currency", default=""): vol.In(currencys),
vol.Optional("VAT", default=True): bool,
vol.Optional("precision", default=3): vol.Coerce(int),
vol.Optional("low_price_cutoff", default=1.0): vol.Coerce(float),
vol.Optional("price_in_cents", default=False): bool,
vol.Optional("price_type", default="kWh"): vol.In(price_types),
vol.Optional("additional_costs", default=""): str,
}
return self.async_update_reload_and_abort(
self._config_entry,
data=user_input,
reason="reconfigure_successful",
)

return self.async_show_form(
step_id="reconfigure_confirm", **self._get_form_data(self._config_entry.data),
errors=self._errors
)

placeholders = {
"region": regions,
"currency": currencys,
"price_type": price_types,
def _get_form_data(self, user_input: "Mapping[str, Any] | None"):
"""Populate form data from user input and default values"""
if not user_input:
user_input = dict()

data_schema = vol.Schema({
vol.Required("region", default=user_input.get("region", None)): vol.In(regions),
vol.Required("currency", default=user_input.get("currency", None)): vol.In(currencys),
vol.Optional("VAT", default=user_input.get("VAT", True)): bool,
vol.Required("precision", default=user_input.get("precision", 3)): vol.Coerce(int),
vol.Required("low_price_cutoff", default=user_input.get("low_price_cutoff", 1.0)): vol.Coerce(float),
vol.Optional("price_in_cents", default=user_input.get("price_in_cents", False)): bool,
vol.Required("price_type", default=user_input.get("price_type", "kWh")): vol.In(price_types),
vol.Optional("additional_costs", default=user_input.get("additional_costs", "") or DEFAULT_TEMPLATE): str,
})

description_placeholders = {
"price_type": price_types[0],
"additional_costs": "{{0.0|float}}",
}

return self.async_show_form(
step_id="user",
data_schema=vol.Schema(data_schema),
description_placeholders=placeholders,
errors=self._errors,
return dict(description_placeholders=description_placeholders, data_schema=data_schema)

def _patch_template(self, user_template: str):
"""Fix common mistakes in template"""
# Lets try to remove the most common mistakes, this will still fail if the template
# was writte in notepad or something like that..
user_template = re.sub(
r"\s{2,}", "", user_template
)

async def _valid_template(self, user_template):
"""Validate template"""
try:
#
ut = Template(user_template, self.hass).async_render(
Expand Down
39 changes: 39 additions & 0 deletions custom_components/nordpool/strings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{
"config": {
"title": "Nordpool",
"step": {
"user": {
"title": "Nordpool Sensor",
"description": "Setup a Nordpool sensor",
"data": {
"region": "Region",
"currency": "Currency",
"VAT": "Include VAT",
"precision": "Decimal rounding precision",
"low_price_cutoff": "Low price percentage",
"price_in_cents": "Price in cents",
"price_type": "Energy scale",
"additional_costs": "Template for additional costs"
},
"reconfigure_confirm": {
"title": "Nordpool Sensor",
"description": "Reconfigure Nordpool sensor",
"data": {
"region": "Region",
"currency": "Currency",
"VAT": "Include VAT",
"precision": "Decimal rounding precision",
"low_price_cutoff": "Low price percentage",
"price_in_cents": "Price in cents",
"price_type": "Energy scale",
"additional_costs": "Template for additional costs"
}
}
}
},
"error": {
"name_exists": "Name already exists",
"invalid_template": "The template is invalid, check https://github.com/custom-components/nordpool"
}
}
}
16 changes: 15 additions & 1 deletion custom_components/nordpool/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,25 @@
"price_type": "Energy scale",
"additional_costs": "Template for additional costs"
}
},
"reconfigure_confirm": {
"title": "Nordpool Sensor",
"description": "Reconfigure a Nordpool sensor",
"data": {
"region": "Region",
"currency": "Currency",
"VAT": "Include VAT",
"precision": "Decimal rounding precision",
"low_price_cutoff": "Low price percentage",
"price_in_cents": "Price in cents",
"price_type": "Energy scale",
"additional_costs": "Template for additional costs"
}
}
},
"error": {
"name_exists": "Name already exists",
"invalid_template": "The template is invalid, check https://github.com/custom-components/nordpool"
}
}
}
}
21 changes: 18 additions & 3 deletions custom_components/nordpool/translations/sv.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,27 @@
"title": "Nord Pool",
"step": {
"user": {
"title": "Sensor",
"title": "Nordpool Sensor",
"description": "Konfigurera en Nord Pool-sensor",
"data": {
"region": "Region",
"friendly_name": "Visningsnamn",
"currency": "SEK",
"currency": "Valuta",
"VAT": "Inkludera moms",
"precision": "Hur många decimaler ska visas",
"low_price_cutoff": "Lägsta prisnivå",
"price_in_cents": "Pris i ören",
"price_type": "Prisformat",
"additional_costs": "Mall för ytterligare kostnader"
}
},
"reconfigure_confirm": {
"title": "Nordpool Sensor",
"description": "Konfigurera en Nord Pool-sensor",
"data": {
"region": "Region",
"friendly_name": "Visningsnamn",
"currency": "Valuta",
"VAT": "Inkludera moms",
"precision": "Hur många decimaler ska visas",
"low_price_cutoff": "Lägsta prisnivå",
Expand All @@ -23,4 +38,4 @@
"invalid_template": "Mallen är ogiltig, se https://github.com/custom-components/nordpool"
}
}
}
}

0 comments on commit ec3b21a

Please sign in to comment.