-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig_flow.py
More file actions
139 lines (114 loc) · 4.81 KB
/
Copy pathconfig_flow.py
File metadata and controls
139 lines (114 loc) · 4.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
from __future__ import annotations
import voluptuous as vol
from homeassistant import config_entries
from homeassistant.data_entry_flow import FlowResult
from .const import (
CONF_INCLUDE_PSCR,
CONF_NET_METERING,
CONF_SELECTED_RATE,
CONF_TAX_RATE,
DEFAULT_INCLUDE_PSCR,
DEFAULT_TAX_RATE_PERCENT,
DOMAIN,
)
from .coordinator import DteRateCoordinator
from .settings import normalize_tax_rate_percent
class DteRatesConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1
@staticmethod
def async_get_options_flow(config_entry) -> config_entries.OptionsFlow:
return DteRatesOptionsFlow(config_entry)
async def async_step_user(self, user_input: dict | None = None) -> FlowResult:
coordinator = DteRateCoordinator(self.hass)
await coordinator.async_refresh()
if coordinator.data is None:
return self.async_abort(reason="cannot_connect")
rate_options = {
code: f"{rate.name} ({code})"
for code, rate in coordinator.data.rates.items()
}
errors: dict[str, str] = {}
if user_input is not None:
try:
data = _normalize_config_input(user_input)
except ValueError:
errors["base"] = "invalid_tax_rate"
else:
selected_rate = data[CONF_SELECTED_RATE]
return self.async_create_entry(
title=rate_options[selected_rate],
data=data,
)
schema = _user_schema(rate_options)
return self.async_show_form(
step_id="user",
data_schema=schema,
errors=errors,
description_placeholders={
"rider18_status": _rider18_status(coordinator.data),
"tax_note": _tax_note(),
},
)
class DteRatesOptionsFlow(config_entries.OptionsFlow):
def __init__(self, config_entry) -> None:
self.config_entry = config_entry
async def async_step_init(self, user_input: dict | None = None) -> FlowResult:
errors: dict[str, str] = {}
if user_input is not None:
try:
data = _normalize_options_input(user_input)
except ValueError:
errors["base"] = "invalid_tax_rate"
else:
return self.async_create_entry(title="", data=data)
return self.async_show_form(
step_id="init",
data_schema=_options_schema(self.config_entry),
errors=errors,
description_placeholders={"tax_note": _tax_note()},
)
def _normalize_config_input(user_input: dict) -> dict:
data = dict(user_input)
data.setdefault(CONF_INCLUDE_PSCR, DEFAULT_INCLUDE_PSCR)
data.setdefault(CONF_TAX_RATE, DEFAULT_TAX_RATE_PERCENT)
data[CONF_INCLUDE_PSCR] = bool(data[CONF_INCLUDE_PSCR])
data[CONF_TAX_RATE] = normalize_tax_rate_percent(data[CONF_TAX_RATE])
return data
def _normalize_options_input(user_input: dict) -> dict:
data = {
CONF_INCLUDE_PSCR: bool(user_input.get(CONF_INCLUDE_PSCR, DEFAULT_INCLUDE_PSCR)),
CONF_TAX_RATE: normalize_tax_rate_percent(user_input.get(CONF_TAX_RATE, DEFAULT_TAX_RATE_PERCENT)),
}
return data
def _user_schema(rate_options: dict[str, str]) -> vol.Schema:
return vol.Schema(
{
vol.Required(CONF_SELECTED_RATE): vol.In(rate_options),
vol.Optional(CONF_NET_METERING, default=False): bool,
vol.Optional(CONF_INCLUDE_PSCR, default=DEFAULT_INCLUDE_PSCR): bool,
vol.Optional(CONF_TAX_RATE, default=DEFAULT_TAX_RATE_PERCENT): str,
}
)
def _options_schema(config_entry) -> vol.Schema:
options = getattr(config_entry, "options", None) or {}
data = getattr(config_entry, "data", None) or {}
include_pscr = options.get(CONF_INCLUDE_PSCR, data.get(CONF_INCLUDE_PSCR, DEFAULT_INCLUDE_PSCR))
tax_rate = options.get(CONF_TAX_RATE, data.get(CONF_TAX_RATE, DEFAULT_TAX_RATE_PERCENT))
return vol.Schema(
{
vol.Optional(CONF_INCLUDE_PSCR, default=include_pscr): bool,
vol.Optional(CONF_TAX_RATE, default=tax_rate): str,
}
)
def _rider18_status(rate_card) -> str:
count = len(getattr(rate_card, "pscr_rates", {}))
if count:
suffix = "tariff" if count == 1 else "tariffs"
return f"Rider 18 export credits use parsed generation rates plus MPSC PSCR factors loaded for {count} {suffix}."
return "Rider 18 export credits use parsed generation rates plus MPSC PSCR when the selected tariff has a PSCR factor."
def _tax_note() -> str:
return (
"Default tax is Michigan's 4.0% residential electric sales tax. "
"Detroit residents may incur an additional 5.0% City Utility Users' Tax. "
"Set tax rate to 0 to omit taxes from rate calculations."
)