-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add ability to show and hide entities position on map. (close #209)
- Loading branch information
Showing
11 changed files
with
194 additions
and
170 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,33 @@ | ||
# Copyright (c) 2019-2024, Andrey "Limych" Khrolenok <[email protected]> | ||
# Creative Commons BY-NC-SA 4.0 International Public License | ||
# (see LICENSE.md or https://creativecommons.org/licenses/by-nc-sa/4.0/) | ||
"""The Gismeteo component. | ||
""" | ||
The Gismeteo component. | ||
For more details about this platform, please refer to the documentation at | ||
https://github.com/Limych/ha-gismeteo/ | ||
""" | ||
|
||
from functools import cached_property | ||
import logging | ||
from functools import cached_property | ||
|
||
import homeassistant.helpers.config_validation as cv | ||
import voluptuous as vol | ||
from aiohttp import ClientConnectorError | ||
from async_timeout import timeout | ||
import voluptuous as vol | ||
|
||
from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry | ||
from homeassistant.const import ( | ||
CONF_API_KEY, | ||
CONF_DOMAIN, | ||
CONF_LATITUDE, | ||
CONF_LONGITUDE, | ||
CONF_NAME, | ||
CONF_SENSORS, | ||
CONF_SHOW_ON_MAP, | ||
) | ||
from homeassistant.core import HomeAssistant | ||
from homeassistant.exceptions import ConfigEntryNotReady | ||
from homeassistant.helpers.aiohttp_client import async_get_clientsession | ||
import homeassistant.helpers.config_validation as cv | ||
from homeassistant.helpers.storage import STORAGE_DIR | ||
from homeassistant.helpers.typing import ConfigType | ||
from homeassistant.helpers.update_coordinator import ( | ||
|
@@ -38,7 +40,9 @@ | |
from .const import ( | ||
CONF_ADD_SENSORS, | ||
CONF_CACHE_DIR, | ||
CONF_CACHE_TIME, | ||
CONF_FORECAST_DAYS, | ||
CONF_TIMEZONE, | ||
COORDINATOR, | ||
DOMAIN, | ||
DOMAIN_YAML, | ||
|
@@ -59,6 +63,7 @@ | |
vol.Optional(CONF_API_KEY): cv.string, | ||
vol.Optional(CONF_LATITUDE): cv.latitude, | ||
vol.Optional(CONF_LONGITUDE): cv.longitude, | ||
vol.Optional(CONF_SHOW_ON_MAP, default=False): cv.boolean, | ||
vol.Optional(CONF_SENSORS): cv.deprecated, | ||
vol.Optional(CONF_ADD_SENSORS, default=False): cv.boolean, | ||
vol.Optional(CONF_FORECAST_DAYS): forecast_days_int, | ||
|
@@ -72,7 +77,7 @@ | |
) | ||
|
||
|
||
def deslugify(text: str): | ||
def deslugify(text: str) -> str: | ||
"""Deslugify string.""" | ||
return text.replace("_", " ").capitalize() | ||
|
||
|
@@ -107,15 +112,18 @@ def _get_api_client( | |
latitude=config.get(CONF_LATITUDE, hass.config.latitude), | ||
longitude=config.get(CONF_LONGITUDE, hass.config.longitude), | ||
params={ | ||
"domain": DOMAIN, | ||
"timezone": str(hass.config.time_zone), | ||
"cache_dir": config.get(CONF_CACHE_DIR, hass.config.path(STORAGE_DIR)), | ||
"cache_time": UPDATE_INTERVAL.total_seconds(), | ||
CONF_DOMAIN: DOMAIN, | ||
CONF_TIMEZONE: str(hass.config.time_zone), | ||
CONF_CACHE_DIR: config.get(CONF_CACHE_DIR, hass.config.path(STORAGE_DIR)), | ||
CONF_CACHE_TIME: UPDATE_INTERVAL.total_seconds(), | ||
CONF_SHOW_ON_MAP: config.get(CONF_SHOW_ON_MAP, False), | ||
}, | ||
) | ||
|
||
|
||
async def _async_get_coordinator(hass: HomeAssistant, unique_id, config: dict): | ||
async def _async_get_coordinator( | ||
hass: HomeAssistant, unique_id: str | None, config: dict | ||
) -> DataUpdateCoordinator: | ||
"""Prepare update coordinator instance.""" | ||
gismeteo = _get_api_client(hass, config) | ||
await gismeteo.async_update_location() | ||
|
@@ -173,7 +181,7 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: | |
return unload_ok | ||
|
||
|
||
async def update_listener(hass: HomeAssistant, entry: ConfigEntry): | ||
async def update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: | ||
"""Update listener.""" | ||
await hass.config_entries.async_reload(entry.entry_id) | ||
|
||
|
@@ -183,7 +191,7 @@ class GismeteoDataUpdateCoordinator(DataUpdateCoordinator): | |
|
||
def __init__( | ||
self, hass: HomeAssistant, unique_id: str | None, gismeteo: GismeteoApiClient | ||
): | ||
) -> None: | ||
"""Initialize.""" | ||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=UPDATE_INTERVAL) | ||
|
||
|
@@ -200,7 +208,7 @@ async def _async_update_data(self) -> _DataT: | |
try: | ||
async with timeout(10): | ||
await self.gismeteo.async_update() | ||
return self.gismeteo.current_data | ||
|
||
except (ApiError, ClientConnectorError) as error: | ||
raise UpdateFailed(error) from error | ||
else: | ||
return self.gismeteo.current_data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,30 @@ | ||
# Copyright (c) 2019-2021, Andrey "Limych" Khrolenok <[email protected]> | ||
# Creative Commons BY-NC-SA 4.0 International Public License | ||
# (see LICENSE.md or https://creativecommons.org/licenses/by-nc-sa/4.0/) | ||
"""The Gismeteo component. | ||
""" | ||
The Gismeteo component. | ||
For more details about this platform, please refer to the documentation at | ||
https://github.com/Limych/ha-gismeteo/ | ||
""" | ||
|
||
import logging | ||
from collections.abc import Mapping | ||
from typing import Any | ||
|
||
import homeassistant.helpers.config_validation as cv | ||
import voluptuous as vol | ||
from aiohttp import ClientConnectorError, ClientError | ||
from async_timeout import timeout | ||
import voluptuous as vol | ||
|
||
from homeassistant import config_entries | ||
from homeassistant.config_entries import SOURCE_IMPORT | ||
from homeassistant.const import CONF_LATITUDE, CONF_LONGITUDE, CONF_NAME | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.const import ( | ||
CONF_LATITUDE, | ||
CONF_LONGITUDE, | ||
CONF_NAME, | ||
CONF_SHOW_ON_MAP, | ||
) | ||
from homeassistant.core import callback | ||
import homeassistant.helpers.config_validation as cv | ||
|
||
from . import _get_api_client, forecast_days_int # pylint: disable=unused-import | ||
from .api import ApiError | ||
|
@@ -29,19 +36,24 @@ | |
|
||
_LOGGER = logging.getLogger(__name__) | ||
|
||
type ConfigType = Mapping[str, Any] | None | ||
|
||
|
||
class GismeteoFlowHandler(config_entries.ConfigFlow, domain=DOMAIN): | ||
"""Config flow for Gismeteo.""" | ||
|
||
VERSION = 1 | ||
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL | ||
|
||
def __init__(self): | ||
def __init__(self) -> None: | ||
"""Init config flow.""" | ||
self._errors = {} | ||
|
||
async def async_step_import(self, platform_config): | ||
"""Import a config entry. | ||
async def async_step_import( | ||
self, platform_config: ConfigType | ||
) -> config_entries.ConfigFlowResult: | ||
""" | ||
Import a config entry. | ||
Special type of import, we're not actually going to store any data. | ||
Instead, we're going to rely on the values that are in config file. | ||
|
@@ -51,10 +63,12 @@ async def async_step_import(self, platform_config): | |
|
||
return self.async_create_entry(title="configuration.yaml", data=platform_config) | ||
|
||
async def async_step_user(self, user_input=None): | ||
async def async_step_user( | ||
self, user_input: ConfigType = None | ||
) -> config_entries.ConfigFlowResult: | ||
"""Handle a flow initialized by the user.""" | ||
for entry in self._async_current_entries(): | ||
if entry.source == SOURCE_IMPORT: | ||
if entry.source == config_entries.SOURCE_IMPORT: | ||
return self.async_abort(reason="no_mixed_config") | ||
|
||
self._errors = {} | ||
|
@@ -73,7 +87,7 @@ async def async_step_user(self, user_input=None): | |
|
||
return self._show_config_form(user_input) | ||
|
||
def _show_config_form(self, config): | ||
def _show_config_form(self, config: ConfigType) -> config_entries.ConfigFlowResult: | ||
if config is None: | ||
config = {} | ||
return self.async_show_form( | ||
|
@@ -99,27 +113,31 @@ def _show_config_form(self, config): | |
|
||
@staticmethod | ||
@callback | ||
def async_get_options_flow(config_entry): | ||
def async_get_options_flow(config_entry: ConfigEntry) -> config_entries.OptionsFlow: | ||
"""Get component options flow.""" | ||
return GismeteoOptionsFlowHandler(config_entry) | ||
|
||
|
||
class GismeteoOptionsFlowHandler(config_entries.OptionsFlow): | ||
"""Gismeteo config flow options handler.""" | ||
|
||
def __init__(self, config_entry): | ||
def __init__(self, config_entry: ConfigEntry) -> None: | ||
"""Initialize HACS options flow.""" | ||
self.config_entry = config_entry | ||
self.options = dict(config_entry.options) | ||
|
||
async def async_step_init(self, user_input=None): # pylint: disable=unused-argument | ||
async def async_step_init( | ||
self, user_input: ConfigType = None # noqa: ARG002 | ||
) -> config_entries.ConfigFlowResult: # pylint: disable=unused-argument | ||
"""Manage the options.""" | ||
if self.config_entry.source == config_entries.SOURCE_IMPORT: | ||
return self.async_abort(reason="no_options_available") | ||
|
||
return await self.async_step_user() | ||
|
||
async def async_step_user(self, user_input: dict | None = None): | ||
async def async_step_user( | ||
self, user_input: ConfigType = None | ||
) -> config_entries.ConfigFlowResult: | ||
"""Handle a flow initialized by the user.""" | ||
if user_input is not None: | ||
if CONF_FORECAST_DAYS in self.options: | ||
|
@@ -132,6 +150,10 @@ async def async_step_user(self, user_input: dict | None = None): | |
data_schema=self.add_suggested_values_to_schema( | ||
vol.Schema( | ||
{ | ||
vol.Required( | ||
CONF_SHOW_ON_MAP, | ||
default=self.options.get(CONF_SHOW_ON_MAP, False), | ||
): bool, | ||
vol.Required(CONF_ADD_SENSORS, default=False): bool, | ||
vol.Optional(CONF_FORECAST_DAYS): forecast_days_int, | ||
} | ||
|
@@ -140,7 +162,7 @@ async def async_step_user(self, user_input: dict | None = None): | |
), | ||
) | ||
|
||
async def _update_options(self): | ||
async def _update_options(self) -> config_entries.ConfigFlowResult: | ||
"""Update config entry options.""" | ||
return self.async_create_entry( | ||
title=self.config_entry.data.get(CONF_NAME), data=self.options | ||
|
Oops, something went wrong.