Skip to content

Commit

Permalink
v2024.4.3 adds config flow
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroenterheerdt committed Apr 12, 2024
1 parent a3d71fd commit 4830125
Show file tree
Hide file tree
Showing 9 changed files with 314 additions and 39 deletions.
102 changes: 85 additions & 17 deletions custom_components/daily/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
EVENT_UPDATE,
SERVICE_RESET,
SERVICE_UPDATE,
COORDINATOR,
)

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

# update listener for options flow
hass_data = dict(entry.data)
unsub_options_update_listener = entry.add_update_listener(options_update_listener)
hass_data["unsub_options_update_listener"] = unsub_options_update_listener
hass.data[DOMAIN][entry.entry_id] = hass_data

# logic here is: if options are set that do not agree with the data settings, use the options
# handle options flow data
if CONF_INPUT_SENSOR in entry.options and entry.options.get(
CONF_INPUT_SENSOR
) != entry.data.get(CONF_INPUT_SENSOR):
input_sensor = hass.data[DOMAIN][entry.entry_id][
CONF_INPUT_SENSOR
] = entry.options.get(CONF_INPUT_SENSOR)
if CONF_AUTO_RESET in entry.options and entry.options.get(
CONF_AUTO_RESET
) != entry.data.get(CONF_AUTO_RESET):
auto_reset = hass.data[DOMAIN][entry.entry_id][
CONF_AUTO_RESET
] = entry.options.get(CONF_AUTO_RESET)
if CONF_INTERVAL in entry.options and entry.options.get(
CONF_INTERVAL
) != entry.data.get(CONF_INTERVAL):
interval = hass.data[DOMAIN][entry.entry_id][CONF_INTERVAL] = entry.options.get(
CONF_INTERVAL
)
if CONF_OPERATION in entry.options and entry.options.get(
CONF_OPERATION
) != entry.data.get(CONF_OPERATION):
operation = hass.data[DOMAIN][entry.entry_id][
CONF_OPERATION
] = entry.options.get(CONF_OPERATION)
if CONF_UNIT_OF_MEASUREMENT in entry.options and entry.options.get(
CONF_UNIT_OF_MEASUREMENT
) != entry.data.get(CONF_UNIT_OF_MEASUREMENT):
unit_of_measurement = hass.data[DOMAIN][entry.entry_id][
CONF_UNIT_OF_MEASUREMENT
] = entry.options.get(CONF_UNIT_OF_MEASUREMENT)
# set up coordinator
coordinator = DailySensorUpdateCoordinator(
hass,
Expand All @@ -63,18 +102,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
if not coordinator.last_update_success:
raise ConfigEntryNotReady

hass.data[DOMAIN][entry.entry_id] = coordinator

for platform in PLATFORMS:
coordinator.platforms.append(platform)
hass.async_create_task(
hass.config_entries.async_forward_entry_setup(entry, platform)
)

# add update listener if not already added.
if weakref.ref(async_reload_entry) not in entry.update_listeners:
entry.add_update_listener(async_reload_entry)
# if weakref.ref(async_reload_entry) not in entry.update_listeners:
# entry.add_update_listener(async_reload_entry)

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

async def async_reload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Reload config entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]
coordinator = hass.data[DOMAIN][entry.entry_id][COORDINATOR]
if coordinator.entry_setup_completed:
await async_unload_entry(hass, entry)
await async_setup_entry(hass, entry)


async def options_update_listener(hass, config_entry):
"""Handle options update."""
hass.data[DOMAIN][config_entry.entry_id][CONF_INTERVAL] = config_entry.options.get(
CONF_INTERVAL
)
hass.data[DOMAIN][config_entry.entry_id][
CONF_INPUT_SENSOR
] = config_entry.options.get(CONF_INPUT_SENSOR)
hass.data[DOMAIN][config_entry.entry_id][
CONF_AUTO_RESET
] = config_entry.options.get(CONF_AUTO_RESET)
hass.data[DOMAIN][config_entry.entry_id][CONF_OPERATION] = config_entry.options.get(
CONF_OPERATION
)
hass.data[DOMAIN][config_entry.entry_id][
CONF_UNIT_OF_MEASUREMENT
] = config_entry.options.get(CONF_UNIT_OF_MEASUREMENT)
await hass.config_entries.async_reload(config_entry.entry_id)


async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
"""Handle removal of an entry."""
coordinator = hass.data[DOMAIN][entry.entry_id]
unloaded = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(entry, platform)
for platform in PLATFORMS
if platform in coordinator.platforms
]
if DOMAIN in hass.data and entry.entry_id in hass.data[DOMAIN]:
coordinator = hass.data[DOMAIN][entry.entry_id][COORDINATOR]
unloaded = all(
await asyncio.gather(
*[
hass.config_entries.async_forward_entry_unload(entry, platform)
for platform in PLATFORMS
if platform in coordinator.platforms
]
)
)
)
if unloaded:
hass.data[DOMAIN].pop(entry.entry_id)
if unloaded:
hass.data[DOMAIN].pop(entry.entry_id)

return unloaded
return True


return unloaded
async def async_remove_entry(hass, entry):
"""Remove Daily sensor config entry."""
if DOMAIN in hass.data and entry.entry_id in hass.data[DOMAIN]:
coordinator = hass.data[DOMAIN][entry.entry_id]["coordinator"]
await coordinator.async_delete_config()
del hass.data[DOMAIN][entry.entry_id]


class DailySensorUpdateCoordinator(DataUpdateCoordinator):
Expand Down
29 changes: 11 additions & 18 deletions custom_components/daily/config_flow.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Config flow for Daily Sensor integration."""

from homeassistant.core import callback
from .const import ( # pylint: disable=unused-import
DOMAIN,
CONF_INPUT_SENSOR,
Expand All @@ -12,11 +14,12 @@
DEFAULT_INTERVAL,
DEFAULT_AUTO_RESET,
)

from .exceptions import SensorNotFound, OperationNotFound, IntervalNotValid, NotUnique
from .options_flow import DailySensorOptionsFlowHandler
import logging
import voluptuous as vol

from homeassistant import config_entries, exceptions
from homeassistant import config_entries

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -106,23 +109,13 @@ async def _show_config_form(self, user_input):
errors=self._errors,
)

@staticmethod
@callback
def async_get_options_flow(config_entry):
"""Get options flow."""
return DailySensorOptionsFlowHandler(config_entry)

async def _check_unique(self, thename):
"""Test if the specified name is not already claimed."""
await self.async_set_unique_id(thename)
self._abort_if_unique_id_configured()


class SensorNotFound(exceptions.HomeAssistantError):
"""Error to indicate a sensor is not found."""


class OperationNotFound(exceptions.HomeAssistantError):
"""Error to indicate the operation specified is not valid."""


class IntervalNotValid(exceptions.HomeAssistantError):
"""Error to indicate the interval specified is not valid."""


class NotUnique(exceptions.HomeAssistantError):
"""Error to indicate that the name is not unique."""
8 changes: 6 additions & 2 deletions custom_components/daily/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
DOMAIN = "daily"
NAME = "Daily Sensor"
DOMAIN_DATA = f"{DOMAIN}_data"
VERSION = "2024.4.2"

VERSION = "2024.4.3"
COORDINATOR = "coordinator"
ISSUE_URL = "https://github.com/jeroenterheerdt/HADailySensor/issues"

# Icons
Expand All @@ -14,6 +14,10 @@
SENSOR = "sensor"
PLATFORMS = [SENSOR]

# Localization
LANGUAGE_FILES_DIR = "translations"
SUPPORTED_LANGUAGES = ["el", "en", "es", "fr", "nb", "nl", "sk"]

# Config
CONF_INPUT_SENSOR = "sensor"
CONF_OPERATION = "operation"
Expand Down
17 changes: 17 additions & 0 deletions custom_components/daily/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from homeassistant import exceptions


class SensorNotFound(exceptions.HomeAssistantError):
"""Error to indicate a sensor is not found."""


class OperationNotFound(exceptions.HomeAssistantError):
"""Error to indicate the operation specified is not valid."""


class IntervalNotValid(exceptions.HomeAssistantError):
"""Error to indicate the interval specified is not valid."""


class NotUnique(exceptions.HomeAssistantError):
"""Error to indicate that the name is not unique."""
50 changes: 50 additions & 0 deletions custom_components/daily/localize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import logging
import json
import os
from .const import LANGUAGE_FILES_DIR, SUPPORTED_LANGUAGES

_LOGGER = logging.getLogger(__name__)


def localize(string, language):
# try opening language file
language = language.lower()
translated_string = None
main_path = os.path.dirname(__file__)
stringpath = string.split(".")
try:
# if the language is not english and the language is supported
if language != "en" and language in SUPPORTED_LANGUAGES:
with open(
os.path.join(
main_path, LANGUAGE_FILES_DIR + os.sep + language + ".json"
)
) as f:
data = json.load(f)
translated_string = get_string_from_data(stringpath, data)
# fallback to english in case string wasn't found
if language == "en" or not isinstance(translated_string, str):
with open(
os.path.join(main_path, LANGUAGE_FILES_DIR + os.sep + "en.json")
) as f:
data = json.load(f)
translated_string = get_string_from_data(stringpath, data)
# if still not found, just return the string parameter
if isinstance(translated_string, str):
return translated_string
else:
return string
except OSError:
_LOGGER.error(
"Couldn't load translations language file for {}".format(language)
)


def get_string_from_data(stringpath, data):
data_to_walk = data
for p in stringpath:
if isinstance(data_to_walk, str):
return data_to_walk
if p in data_to_walk:
data_to_walk = data_to_walk[p]
return data_to_walk
2 changes: 1 addition & 1 deletion custom_components/daily/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
"homekit": {},
"dependencies": [],
"codeowners": ["@jeroenterheerdt"],
"version": "2024.4.2"
"version": "2024.4.3"
}
Loading

0 comments on commit 4830125

Please sign in to comment.