Skip to content

Commit 4830125

Browse files
v2024.4.3 adds config flow
1 parent a3d71fd commit 4830125

File tree

9 files changed

+314
-39
lines changed

9 files changed

+314
-39
lines changed

custom_components/daily/__init__.py

Lines changed: 85 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
EVENT_UPDATE,
2525
SERVICE_RESET,
2626
SERVICE_UPDATE,
27+
COORDINATOR,
2728
)
2829

2930
_LOGGER = logging.getLogger(__name__)
@@ -47,6 +48,44 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
4748
unit_of_measurement = entry.data.get(CONF_UNIT_OF_MEASUREMENT)
4849
auto_reset = entry.data.get(CONF_AUTO_RESET, DEFAULT_AUTO_RESET)
4950

51+
# update listener for options flow
52+
hass_data = dict(entry.data)
53+
unsub_options_update_listener = entry.add_update_listener(options_update_listener)
54+
hass_data["unsub_options_update_listener"] = unsub_options_update_listener
55+
hass.data[DOMAIN][entry.entry_id] = hass_data
56+
57+
# logic here is: if options are set that do not agree with the data settings, use the options
58+
# handle options flow data
59+
if CONF_INPUT_SENSOR in entry.options and entry.options.get(
60+
CONF_INPUT_SENSOR
61+
) != entry.data.get(CONF_INPUT_SENSOR):
62+
input_sensor = hass.data[DOMAIN][entry.entry_id][
63+
CONF_INPUT_SENSOR
64+
] = entry.options.get(CONF_INPUT_SENSOR)
65+
if CONF_AUTO_RESET in entry.options and entry.options.get(
66+
CONF_AUTO_RESET
67+
) != entry.data.get(CONF_AUTO_RESET):
68+
auto_reset = hass.data[DOMAIN][entry.entry_id][
69+
CONF_AUTO_RESET
70+
] = entry.options.get(CONF_AUTO_RESET)
71+
if CONF_INTERVAL in entry.options and entry.options.get(
72+
CONF_INTERVAL
73+
) != entry.data.get(CONF_INTERVAL):
74+
interval = hass.data[DOMAIN][entry.entry_id][CONF_INTERVAL] = entry.options.get(
75+
CONF_INTERVAL
76+
)
77+
if CONF_OPERATION in entry.options and entry.options.get(
78+
CONF_OPERATION
79+
) != entry.data.get(CONF_OPERATION):
80+
operation = hass.data[DOMAIN][entry.entry_id][
81+
CONF_OPERATION
82+
] = entry.options.get(CONF_OPERATION)
83+
if CONF_UNIT_OF_MEASUREMENT in entry.options and entry.options.get(
84+
CONF_UNIT_OF_MEASUREMENT
85+
) != entry.data.get(CONF_UNIT_OF_MEASUREMENT):
86+
unit_of_measurement = hass.data[DOMAIN][entry.entry_id][
87+
CONF_UNIT_OF_MEASUREMENT
88+
] = entry.options.get(CONF_UNIT_OF_MEASUREMENT)
5089
# set up coordinator
5190
coordinator = DailySensorUpdateCoordinator(
5291
hass,
@@ -63,18 +102,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
63102
if not coordinator.last_update_success:
64103
raise ConfigEntryNotReady
65104

66-
hass.data[DOMAIN][entry.entry_id] = coordinator
67-
68105
for platform in PLATFORMS:
69106
coordinator.platforms.append(platform)
70107
hass.async_create_task(
71108
hass.config_entries.async_forward_entry_setup(entry, platform)
72109
)
73110

74111
# add update listener if not already added.
75-
if weakref.ref(async_reload_entry) not in entry.update_listeners:
76-
entry.add_update_listener(async_reload_entry)
112+
# if weakref.ref(async_reload_entry) not in entry.update_listeners:
113+
# entry.add_update_listener(async_reload_entry)
77114

115+
hass.data[DOMAIN][entry.entry_id][COORDINATOR] = coordinator
78116
# register services
79117
hass.services.async_register(
80118
DOMAIN,
@@ -91,28 +129,58 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
91129

92130
async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry):
93131
"""Reload config entry."""
94-
coordinator = hass.data[DOMAIN][entry.entry_id]
132+
coordinator = hass.data[DOMAIN][entry.entry_id][COORDINATOR]
95133
if coordinator.entry_setup_completed:
96134
await async_unload_entry(hass, entry)
97135
await async_setup_entry(hass, entry)
98136

99137

138+
async def options_update_listener(hass, config_entry):
139+
"""Handle options update."""
140+
hass.data[DOMAIN][config_entry.entry_id][CONF_INTERVAL] = config_entry.options.get(
141+
CONF_INTERVAL
142+
)
143+
hass.data[DOMAIN][config_entry.entry_id][
144+
CONF_INPUT_SENSOR
145+
] = config_entry.options.get(CONF_INPUT_SENSOR)
146+
hass.data[DOMAIN][config_entry.entry_id][
147+
CONF_AUTO_RESET
148+
] = config_entry.options.get(CONF_AUTO_RESET)
149+
hass.data[DOMAIN][config_entry.entry_id][CONF_OPERATION] = config_entry.options.get(
150+
CONF_OPERATION
151+
)
152+
hass.data[DOMAIN][config_entry.entry_id][
153+
CONF_UNIT_OF_MEASUREMENT
154+
] = config_entry.options.get(CONF_UNIT_OF_MEASUREMENT)
155+
await hass.config_entries.async_reload(config_entry.entry_id)
156+
157+
100158
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
101159
"""Handle removal of an entry."""
102-
coordinator = hass.data[DOMAIN][entry.entry_id]
103-
unloaded = all(
104-
await asyncio.gather(
105-
*[
106-
hass.config_entries.async_forward_entry_unload(entry, platform)
107-
for platform in PLATFORMS
108-
if platform in coordinator.platforms
109-
]
160+
if DOMAIN in hass.data and entry.entry_id in hass.data[DOMAIN]:
161+
coordinator = hass.data[DOMAIN][entry.entry_id][COORDINATOR]
162+
unloaded = all(
163+
await asyncio.gather(
164+
*[
165+
hass.config_entries.async_forward_entry_unload(entry, platform)
166+
for platform in PLATFORMS
167+
if platform in coordinator.platforms
168+
]
169+
)
110170
)
111-
)
112-
if unloaded:
113-
hass.data[DOMAIN].pop(entry.entry_id)
171+
if unloaded:
172+
hass.data[DOMAIN].pop(entry.entry_id)
173+
174+
return unloaded
175+
return True
176+
114177

115-
return unloaded
178+
async def async_remove_entry(hass, entry):
179+
"""Remove Daily sensor config entry."""
180+
if DOMAIN in hass.data and entry.entry_id in hass.data[DOMAIN]:
181+
coordinator = hass.data[DOMAIN][entry.entry_id]["coordinator"]
182+
await coordinator.async_delete_config()
183+
del hass.data[DOMAIN][entry.entry_id]
116184

117185

118186
class DailySensorUpdateCoordinator(DataUpdateCoordinator):

custom_components/daily/config_flow.py

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""Config flow for Daily Sensor integration."""
2+
3+
from homeassistant.core import callback
24
from .const import ( # pylint: disable=unused-import
35
DOMAIN,
46
CONF_INPUT_SENSOR,
@@ -12,11 +14,12 @@
1214
DEFAULT_INTERVAL,
1315
DEFAULT_AUTO_RESET,
1416
)
15-
17+
from .exceptions import SensorNotFound, OperationNotFound, IntervalNotValid, NotUnique
18+
from .options_flow import DailySensorOptionsFlowHandler
1619
import logging
1720
import voluptuous as vol
1821

19-
from homeassistant import config_entries, exceptions
22+
from homeassistant import config_entries
2023

2124
_LOGGER = logging.getLogger(__name__)
2225

@@ -106,23 +109,13 @@ async def _show_config_form(self, user_input):
106109
errors=self._errors,
107110
)
108111

112+
@staticmethod
113+
@callback
114+
def async_get_options_flow(config_entry):
115+
"""Get options flow."""
116+
return DailySensorOptionsFlowHandler(config_entry)
117+
109118
async def _check_unique(self, thename):
110119
"""Test if the specified name is not already claimed."""
111120
await self.async_set_unique_id(thename)
112121
self._abort_if_unique_id_configured()
113-
114-
115-
class SensorNotFound(exceptions.HomeAssistantError):
116-
"""Error to indicate a sensor is not found."""
117-
118-
119-
class OperationNotFound(exceptions.HomeAssistantError):
120-
"""Error to indicate the operation specified is not valid."""
121-
122-
123-
class IntervalNotValid(exceptions.HomeAssistantError):
124-
"""Error to indicate the interval specified is not valid."""
125-
126-
127-
class NotUnique(exceptions.HomeAssistantError):
128-
"""Error to indicate that the name is not unique."""

custom_components/daily/const.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
DOMAIN = "daily"
44
NAME = "Daily Sensor"
55
DOMAIN_DATA = f"{DOMAIN}_data"
6-
VERSION = "2024.4.2"
7-
6+
VERSION = "2024.4.3"
7+
COORDINATOR = "coordinator"
88
ISSUE_URL = "https://github.com/jeroenterheerdt/HADailySensor/issues"
99

1010
# Icons
@@ -14,6 +14,10 @@
1414
SENSOR = "sensor"
1515
PLATFORMS = [SENSOR]
1616

17+
# Localization
18+
LANGUAGE_FILES_DIR = "translations"
19+
SUPPORTED_LANGUAGES = ["el", "en", "es", "fr", "nb", "nl", "sk"]
20+
1721
# Config
1822
CONF_INPUT_SENSOR = "sensor"
1923
CONF_OPERATION = "operation"

custom_components/daily/exceptions.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from homeassistant import exceptions
2+
3+
4+
class SensorNotFound(exceptions.HomeAssistantError):
5+
"""Error to indicate a sensor is not found."""
6+
7+
8+
class OperationNotFound(exceptions.HomeAssistantError):
9+
"""Error to indicate the operation specified is not valid."""
10+
11+
12+
class IntervalNotValid(exceptions.HomeAssistantError):
13+
"""Error to indicate the interval specified is not valid."""
14+
15+
16+
class NotUnique(exceptions.HomeAssistantError):
17+
"""Error to indicate that the name is not unique."""

custom_components/daily/localize.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import logging
2+
import json
3+
import os
4+
from .const import LANGUAGE_FILES_DIR, SUPPORTED_LANGUAGES
5+
6+
_LOGGER = logging.getLogger(__name__)
7+
8+
9+
def localize(string, language):
10+
# try opening language file
11+
language = language.lower()
12+
translated_string = None
13+
main_path = os.path.dirname(__file__)
14+
stringpath = string.split(".")
15+
try:
16+
# if the language is not english and the language is supported
17+
if language != "en" and language in SUPPORTED_LANGUAGES:
18+
with open(
19+
os.path.join(
20+
main_path, LANGUAGE_FILES_DIR + os.sep + language + ".json"
21+
)
22+
) as f:
23+
data = json.load(f)
24+
translated_string = get_string_from_data(stringpath, data)
25+
# fallback to english in case string wasn't found
26+
if language == "en" or not isinstance(translated_string, str):
27+
with open(
28+
os.path.join(main_path, LANGUAGE_FILES_DIR + os.sep + "en.json")
29+
) as f:
30+
data = json.load(f)
31+
translated_string = get_string_from_data(stringpath, data)
32+
# if still not found, just return the string parameter
33+
if isinstance(translated_string, str):
34+
return translated_string
35+
else:
36+
return string
37+
except OSError:
38+
_LOGGER.error(
39+
"Couldn't load translations language file for {}".format(language)
40+
)
41+
42+
43+
def get_string_from_data(stringpath, data):
44+
data_to_walk = data
45+
for p in stringpath:
46+
if isinstance(data_to_walk, str):
47+
return data_to_walk
48+
if p in data_to_walk:
49+
data_to_walk = data_to_walk[p]
50+
return data_to_walk

custom_components/daily/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,5 @@
1010
"homekit": {},
1111
"dependencies": [],
1212
"codeowners": ["@jeroenterheerdt"],
13-
"version": "2024.4.2"
13+
"version": "2024.4.3"
1414
}

0 commit comments

Comments
 (0)